【问题标题】:How to update bindings inside DataTemplate?如何更新 DataTemplate 中的绑定?
【发布时间】:2021-08-31 00:07:07
【问题描述】:

假设我认为我有以下ListView

<ListView x:Name="ListView1" ItemsSource="{Binding SomeCollection}">
    <ListView.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Do something" Command="{Binding SomeCommand, Mode=OneWay}" />
        </ContextMenu>
    </ListView.ContextMenu>
    <ListView.ItemTemplate>
        <DataTemplate DataType="model:Person">
            <StackLayout>
                <TextBlock Text="{Binding Name}">
                <Image Source="{Binding State, Converter={StaticResource StateToIconConverter}, Mode=OneWay}" />
            </StackLayout>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

现在,这个Person 是一个模型,它的属性没有任何方法可以通知视图它们正在更新(根据 MVVC)。但是,我需要在SomeCommand 执行后更新视图,因为SomeCollection 中的项目会被编辑。

我试过这样做

public void ExecuteSomeCommand() {
    // change the state of some person inside SomeCollection
    (ListView1.SelectedItems[0] as Person).State = "Some different state";

    // now inform the view of change, so it can reflect in the DataTemplate
    ListView1.GetBindingExpression(ListBox.ItemsSourceProperty).UpdateTarget();
}

我认为这会传播到DataTemplate,但事实并非如此。有没有其他方法可以做到这一点?我应该如何改变我的方法?

【问题讨论】:

  • ItemsSource 绑定不是 Image.Source 绑定。当第二个的源属性发生变化时更新第一个是没有意义的。除此之外,考虑让 Person 触发属性更改通知。
  • @Clemens 我知道,但是如果图像控件在 DataTemplate 中,我该如何获取它的引用?
  • 另外注意,不要在未检查 null 的结果的情况下使用 as 运算符。改用显式转换:((Person)ListView1.SelectedItem).State = ...;
  • 让你的模型实现INotifyPropertyChanged.
  • @Clemens 我不会这样使用它,这只是一个示例代码,它反映了我想要做的事情

标签: wpf datatemplate


【解决方案1】:

当数据绑定中使用的模型实现INotifyPropertyChanged Interface时,当您修改模型的属性时,UI会自动更新。

public class Person : INotifyPropertyChanged
{
    private Image _state;
    public Image State
    {
        get => _state;
        set {
            if (value != _state) {
                _state = value;
                OnPropertyChanged(nameof(State));
            }
        }
    }

    // ... other properties here ...

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

【讨论】:

  • State 不应返回 Image,而是 ImageSource - 或任何其他不是 UIElement 且可以通过 OP 的 Binding Converter 转换的东西。例如。一个字符串,正如问题中的代码所暗示的那样。
  • 好的,我的示例必须适应 OP 在其模型类中使用的类型。
猜你喜欢
  • 1970-01-01
  • 2011-12-30
  • 2013-01-14
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
  • 2012-03-17
  • 2022-10-24
相关资源
最近更新 更多