如何正确使用DataBinding、INotifyPropertyChanged、ListViewGridView
How to correctly use DataBinding, INotifyPropertyChanged, ListViewGridView
我 运行 遇到一个问题,试图在 WPF 中更新我的绑定数据。我的数据已显示,但我的 UI 对数据的变化没有反应。
我有一个 XAML Class 看起来像这样:
<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 objects,我想在我的 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 始终为空。
因此没有事件被触发,进度条的值也没有改变。当我通过单击 headers 列之一刷新 UI 时,进度条显示正确的值。显然我想让我的 Progressbar 显示当前进度而无需单击它。
我是 XAML 绑定的新手,希望我没有犯很多基本错误,因此我对所有其他关于如何改进此代码的建议持开放态度。我不太喜欢我在访问 ListViewGridview 构造的项目时受到的限制,但它是我发现的最好的 table,它通过单击列 headers.
进行排序
问题出在
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"));
}
}
一切都是 运行 应该的。
我 运行 遇到一个问题,试图在 WPF 中更新我的绑定数据。我的数据已显示,但我的 UI 对数据的变化没有反应。
我有一个 XAML Class 看起来像这样:
<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 objects,我想在我的 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 始终为空。
因此没有事件被触发,进度条的值也没有改变。当我通过单击 headers 列之一刷新 UI 时,进度条显示正确的值。显然我想让我的 Progressbar 显示当前进度而无需单击它。
我是 XAML 绑定的新手,希望我没有犯很多基本错误,因此我对所有其他关于如何改进此代码的建议持开放态度。我不太喜欢我在访问 ListViewGridview 构造的项目时受到的限制,但它是我发现的最好的 table,它通过单击列 headers.
进行排序问题出在
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"));
}
}
一切都是 运行 应该的。