如何在WPF中刷新绑定?

6

我有一些ObservableCollections与一些WPF控件绑定,它们工作得很好。我有一个功能,完全通过重新分配并再次填充这些ObservableCollections来替换它们,但是在这样做之后,WPF控件不会更新。

或者这个绑定连接只在启动时建立一次,然后我永远不应该重新初始化ObservableCollections,而只是改变它们?

编辑:

public partial class MainWindow : Window
{
    ObservableCollection<EffectViewModel> effects;
    public ObservableCollection<EffectViewModel> Effects
    {
        get { return this.effects; }
        set
        {
            this.effects = value;
            this.RaisePropertyChanged ( "Effects" );
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    void RaisePropertyChanged ( string name )
    {
        var handler = this.PropertyChanged;
        if ( handler != null )
            handler ( this, new PropertyChangedEventArgs ( name ) );
    }
}

public void LoadEffects ( string path, string filename )
{
    //returns new ObservableCollection<EffectViewModel> ( );
    this.Effects = File.Load ( path, filename );
}

public class EffectViewModel
{
    public bool this [ EffectType type ]
    {
        get { return AllEffects.First ( e => e.Type == this.Type ).IsSupported; }
        set
        {
            AllEffects.First ( e => e.Type == this.Type ).IsSupported = value;
            this.RaisePropertyChanged ( "this" );
        }
    }

    #region Events

    public event PropertyChangedEventHandler PropertyChanged;
    void RaisePropertyChanged ( string name )
    {
        var handler = this.PropertyChanged;
        if ( handler != null )
            handler ( this, new PropertyChangedEventArgs ( name ) );
    }

    #endregion
}

编辑2:

<Window x:Class="EffectWindow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="Effect Display" Height="200" Width="700"
    <DockPanel VerticalAlignment="Stretch">

        <ListView
            ItemsSource="{Binding Effects}"
            AlternationCount="2"
            DockPanel.Dock="Top"
            HorizontalContentAlignment="Stretch">

            <ListView.View>
                <GridView>

                    <GridViewColumn
                        Width="70"
                        Header="GPU">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox
                                    Margin="0"
                                    HorizontalAlignment="Center"
                                    IsChecked="{Binding [GPU], Mode=TwoWay}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                    <GridViewColumn
                        Width="70"
                        Header="CPU">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <CheckBox
                                    Margin="0"
                                    HorizontalAlignment="Center"
                                    IsChecked="{Binding [CPU], Mode=TwoWay}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>

                </GridView>
            </ListView.View>
        </ListView>

    </DockPanel>
</Window>

你在将集合改为另一个集合后,是否引发了“PropertyChanged”事件? - BrokenGlass
没有,我没有这样做。那我怎么办呢?我只使用ObservableCollection<Item> MyItems=,所以这不应该由ObservableCollection类型本身引发吗? - Joan Venge
既然您正在创建一个新的集合而不是更改旧的集合,那么它会怎样呢? - BrokenGlass
我知道你的意思。我只是不知道如何在自动属性中挤入一个propertychanged事件,但Pavlo的答案帮助我看到我需要使用一个普通的属性。 - Joan Venge
3个回答

5

您绑定的对象应实现INotifyPropertyChanged接口。然后,绑定的集合属性应该在其设置器中引发PropertyChanged事件。像这样:

public ObservableCollection<MyObject> MyCollection
{
   get
   {
      return _myCollection;
   }
   set
   {
      _myCollection = value;
      RaisePropertyChanged("MyCollection");
   }
} 

1
@Joan - 集合属性应该足够了。如果不起作用,我建议您编辑您的帖子,包括视图模型的相关代码和设置绑定的XAML部分。这将有助于诊断问题。 - Pavlo Glazkov
1
@Joan - 请同时包含包含无法工作的绑定的XAML。您提供的代码看起来不错,除了这一行:this.RaisePropertyChanged("this") - 这行不会起作用,但根据您对问题的描述,这应该无关紧要。 - Pavlo Glazkov
2
@Joan - 好的,现在我明白问题所在了。你的窗口没有继承 INotifyPropertyChanged 接口(EffectViewModel 也是如此)。但它应该这样做:public partial class MainWindow : Window, INotifyPropertyChanged。至于为索引器属性引发 PropertyChanged 事件,指定一个空字符串作为属性名称参数应该可以解决问题。 - Pavlo Glazkov
1
@Joan - 没问题,不用在窗口上实现这些东西。相反,你需要为主窗口创建一个视图模型来公开这些属性。请查看有关MVVM模式的常见问题解答以获取更多信息:https://dev59.com/YnM_5IYBdhLWcg3wXx_Z。 - Pavlo Glazkov
1
@Joan - 嗯,只需查看链接即可 :) 任何MVVM教程都可以回答您的问题。在非常基本的层面上,您需要为应用程序的每个视图创建一个视图模型,而不是数据对象。祝您学习MVVM愉快:) - Pavlo Glazkov
显示剩余6条评论

2

尽量避免重新分配,而是清除并添加新的项目。


谢谢,我会尝试一下。所以如果重新分配的话是不可能的吗? - Joan Venge

0
你需要知道绑定定义的依赖对象和依赖属性。然后,您可以使用以下代码:
BindingOperations.GetBindingExpressionBase(dependencyObject, dependencyProperty).UpdateTarget();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接