【问题标题】:How to correctly use DataBinding, INotifyPropertyChanged, ListViewGridView如何正确使用DataBinding、INotifyPropertyChanged、ListViewGridView
【发布时间】:2015-04-07 04:21:23
【问题描述】:

我遇到了一个问题,试图在 WPF 中更新我的 BoundData。我的数据已显示,但我的 UI 不会对数据的更改做出反应。

我有一个如下所示的 XAML 类:

<Window x:Class="CSharpBoiler.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:util="clr-namespace:Wpf.Util"
    Title="MainWindow" Loaded="Window_Loaded" Closing="Window_Closing" Height="Auto" Width="Auto"
    DataContext="{Binding matchDataList, RelativeSource={RelativeSource Self}}">

<Grid>
    <ListView
  IsSynchronizedWithCurrentItem="True"
  util:GridViewSort.AutoSort="True"
  x:Name="MainListView" >
        <ListView.View>
            <GridView x:Name="MainGridView">
                <GridView.Columns>
                    <GridViewColumn Header="Demo, press to Download"
                            util:GridViewSort.PropertyName="Demo"
                            x:Name="DemoGridViewColumn">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <DockPanel>
                                    <ProgressBar x:Name="DemoButtonProgressbar" 
                                     Maximum="100" Minimum="0" 
                                     Value="{Binding AnalysisProgress,
                                     UpdateSourceTrigger=PropertyChanged}" Width="100"/>
                                </DockPanel>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView.Columns>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

MyMainWindow 如下所示:

    public partial class MainWindow : Window
{
    private List<MatchData> matchDataList = new List<MatchData>();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        MainListView.ItemsSource = matchDataList;
    }

在 matchDataList 中有许多 MatchData 对象,我想在我的 ListViewGridView 中表示它们。 MatchData 看起来像这样:

public class MatchData : ObservableCollection<MatchData>, INotifyPropertyChanged
{
    public int _AnalysisProgress;
    public int AnalysisProgress
    {
        get { return _AnalysisProgress; }
        set
        {
            _AnalysisProgress = value;
            NotifyPropertyChanged("AnalysisProgress");
        }
    }

    public PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

}

此时,我的 Progressbar 显示在我的 ListGridViewgridView 构造中。我在代码中更改它的值以显示进度。当我更改 AnalysisProgress 的值时,NotifyPropertyChanged 被正确调用。但 PropertyChanged 始终为空。

因此不会触发任何事件,进度条的值也不会改变。当我通过单击列标题之一刷新 UI 时,进度条显示正确的值。显然我想让我的进度条显示当前进度而不点击它。

我对 XAML 绑定很陌生,希望我没有犯很多基本错误,因此我对所有其他关于如何改进此代码的建议持开放态度。我不太喜欢我在访问 ListViewGridview 结构的项目时受到的限制,但它是我找到的最好的表,它通过单击列标题进行排序。

【问题讨论】:

  • 尝试将 List 更改为 ObservableCollection。 ObservableCollection matchDataList = new ObservableCollection()
  • @Ganesh 更改了它,PropertyChanged 仍然为 null 并且 UI 没有更新。
  • 你的绑定有问题。
  • 尝试将{Binding AnalysisProgress, UpdateSourceTrigger=PropertyChanged}改为{Binding AnalysisProgress}
  • @AlexeyAdamsky 更改了它,PropertyChanged 仍然为 null 并且 UI 没有更新。

标签: c# wpf xaml listview inotifypropertychanged


【解决方案1】:

问题出在

public class MatchData : ObservableCollection<MatchData>, INotifyPropertyChanged

改成之后

public class MatchData : INotifyPropertyChanged

VS 让我在这样做并修复后实现接口

    public PropertyChangedEventHandler PropertyChanged;

public void NotifyPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

        public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }

    public int _AnalysisProgress;
public int AnalysisProgress
{
    get { return _AnalysisProgress; }
    set
    {
        _AnalysisProgress = value;
        NotifyPropertyChanged("AnalysisProgress");
    }
}

        public int _AnalysisProgress { get; set; }
    public int AnalysisProgress
    {
        get { return _AnalysisProgress; }
        set
        {
            _AnalysisProgress = value;
            OnPropertyChanged(new PropertyChangedEventArgs("AnalysisProgress"));
        }
    }

一切正常。

【讨论】:

  • 这里唯一改变的是:event 被添加,由INotifyPropertyChanged 接口中的事件处理程序定义。
  • 对我来说最重要的是在 XAML 中有一个类似于"{Binding AnalysisProgress, UpdateSourceTrigger=PropertyChanged}"的部分
猜你喜欢
  • 2011-03-31
  • 2015-12-27
  • 2017-06-20
  • 2019-12-15
  • 2020-02-25
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 2019-11-27
相关资源
最近更新 更多