WPF ItemsControl 不刷新
WPF ItemsControl not refreshing
我正在处理一个 WPF 项目。我有一个 class 这样的:
public class Field
{
public ReservationDTO reservation { get; set; }
public DelegateCommand FieldChangeCommand { get; set; }
public bool Available { get; set; }
}
我有 collection 个
public ObservableCollection<Field> Fields { get; set; }
我的观点是这样的
<ItemsControl ItemsSource="{Binding Fields}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid
Columns="{Binding Columns}"
Rows="{Binding Rows}"
/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding FieldChangeCommand}" CommandParameter="{Binding}" Content="{Binding reservation.Statusz}" FontSize="5" IsEnabled="{Binding Available}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这是第一次加载时完美运行。但稍后我可能会更改 Fields 的一些值。例如:(部分viewmodel代码)
Fields[SelectedIndex].reservation.Statusz = "Sold";
Fields[SelectedIndex].Available = false;
OnPropertyChanged("Fields");
OnPropertyChanged("Available");
确保在此之后更新字段,因为视图上的其他元素(如文本框)会刷新。但是视图上的按钮网格不会更新为字段的新值。
谁能告诉我为什么,以及如何解决这个问题?
按钮的内容绑定到 ReservationDTO class 上的 Statusz 属性,这意味着需要实施 INotifyPropertyChanged 才能将按钮内容更改为 "Sold" .可以理解,您不希望它出现在您的 DTO class.
对 OnPropertyChanged 的调用在我看来也是错误的(我假设您的 ViewModel 上有字段 属性 并且 class 是从 ViewModelBase 继承的吗?
您需要执行如下操作(请注意我没有为您的 _reservation 字段添加任何空引用检查):
public class Field : INotifyPropertyChanged
{
private bool _available;
private ReservationDTO _reservation;
public string Statusz
{
get
{
return _reservation.Statusz;
}
set
{
if (_reservation.Statusz != value)
{
_reservation.Statusz = value;
OnPropertyChanged("Available");
}
}
}
public DelegateCommand FieldChangeCommand { get; set; }
public bool Available
{
get
{
return _available;
}
set
{
if (_available != value)
{
_available = value;
OnPropertyChanged("Available");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var localHandler = this.PropertyChanged;
if (localHandler != null)
{
localHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
然后将您的按钮绑定更改为:
<Button Command="{Binding FieldChangeCommand}" CommandParameter="{Binding}" Content="{Binding Statusz}" FontSize="5" IsEnabled="{Binding Available}"/>
我正在处理一个 WPF 项目。我有一个 class 这样的:
public class Field
{
public ReservationDTO reservation { get; set; }
public DelegateCommand FieldChangeCommand { get; set; }
public bool Available { get; set; }
}
我有 collection 个
public ObservableCollection<Field> Fields { get; set; }
我的观点是这样的
<ItemsControl ItemsSource="{Binding Fields}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid
Columns="{Binding Columns}"
Rows="{Binding Rows}"
/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding FieldChangeCommand}" CommandParameter="{Binding}" Content="{Binding reservation.Statusz}" FontSize="5" IsEnabled="{Binding Available}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这是第一次加载时完美运行。但稍后我可能会更改 Fields 的一些值。例如:(部分viewmodel代码)
Fields[SelectedIndex].reservation.Statusz = "Sold";
Fields[SelectedIndex].Available = false;
OnPropertyChanged("Fields");
OnPropertyChanged("Available");
确保在此之后更新字段,因为视图上的其他元素(如文本框)会刷新。但是视图上的按钮网格不会更新为字段的新值。
谁能告诉我为什么,以及如何解决这个问题?
按钮的内容绑定到 ReservationDTO class 上的 Statusz 属性,这意味着需要实施 INotifyPropertyChanged 才能将按钮内容更改为 "Sold" .可以理解,您不希望它出现在您的 DTO class.
对 OnPropertyChanged 的调用在我看来也是错误的(我假设您的 ViewModel 上有字段 属性 并且 class 是从 ViewModelBase 继承的吗?
您需要执行如下操作(请注意我没有为您的 _reservation 字段添加任何空引用检查):
public class Field : INotifyPropertyChanged
{
private bool _available;
private ReservationDTO _reservation;
public string Statusz
{
get
{
return _reservation.Statusz;
}
set
{
if (_reservation.Statusz != value)
{
_reservation.Statusz = value;
OnPropertyChanged("Available");
}
}
}
public DelegateCommand FieldChangeCommand { get; set; }
public bool Available
{
get
{
return _available;
}
set
{
if (_available != value)
{
_available = value;
OnPropertyChanged("Available");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var localHandler = this.PropertyChanged;
if (localHandler != null)
{
localHandler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
然后将您的按钮绑定更改为:
<Button Command="{Binding FieldChangeCommand}" CommandParameter="{Binding}" Content="{Binding Statusz}" FontSize="5" IsEnabled="{Binding Available}"/>