WPF ObservableCollection 绑定到 DataGrid 不刷新 UI
WPF ObservableCollection binding to DataGrid not refreshing UI
我目前面临的问题是我的 DataGrid 绑定没有刷新 UI。
我的 ViewModel 和 Object 继承自 INotifyPropertyChanged。
这是我的代码:
XAML:
<DataGrid Grid.Row="2" DataContext="{StaticResource MainViewModel}" ItemsSource="{Binding TestCollection, Mode=OneWay}" AutoGenerateColumns="True"/>
视图模型:
public class MainViewModel: ViewModelBase
{
private ObservableCollection<ProductDisplayItem> _testCollection;
public ObservableCollection<ProductDisplayItem> TestCollection
{
get => _testCollection;
set => SetProperty(ref _testCollection, value);
}
private async void SendSearch()
{
//MyCode
.....
IEnumerable<ProductDisplayItem> displayItems = DisplayItemHelper.ConvertToDisplayItems(products);
TestCollection = new ObservableCollection<ProductDisplayItem>(displayItems);
}
}
我的对象:
public class ProductDisplayItem: ViewModelBase
{
private string _mfrPartNumber;
private double _unitPrice;
private int _stock;
public string MfrPartNumber
{
get => _mfrPartNumber;
set => SetProperty(ref _mfrPartNumber, value);
}
public double UnitPrice
{
get => _unitPrice;
set => SetProperty(ref _unitPrice, value);
}
public int Stock
{
get => _stock;
set => SetProperty(ref _stock , value);
}
public ProductDisplayItem()
{
}
public ProductDisplayItem(string mfrp, double unitPrice, int stock)
{
MfrPartNumber = mfrp;
UnitPrice = unitPrice;
Stock = stock;
}
}
还有我的 ViewModelBase:
public abstract class ViewModelBase: IDisposable, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
public void Dispose()
{
}
}
我也尝试将项目添加到 ObservableCollection 而不是创建一个新项目,但结果相同。
我希望任何人都可以帮助我。
提前致谢
好的,我明白了。这是数据上下文...
从 xaml.
中删除后工作正常
此类错误的最常见原因是对 ViewModel 实例的混淆:UI 元素绑定到一个实例,而您正在修改另一个实例中的集合。
由于 WPF MVVM 通常只提供在一个实例中使用主 ViewModel,请尝试使用 Singleton。
有类似问题的新主题:
那里的第一个实施选项:
1) 如果:
- 一般来说,原则上,在任何情况下都不会假设一个 ViewModel 在创建它的程序集级别上可以有多个实例;
- 如果这不会造成任何安全问题,因为每个人都可以访问静态实例;
- 如果静态值足以创建单个实例。在大多数情况下,这意味着 ViewModel 只有一个非参数化构造函数。
那么在这种情况下,使用单例是值得的。
示例:
public class MainWindowViewModel : ViewModelBase
{
// The only instance available outside of this class.
public static MainWindowViewModel Instanse { get; }
= new MainWindowViewModel();
// All constructors must be MANDATORY HIDDEN.
private MainWindowViewModel()
{
// Some code
}
// Some code
}
要在 XAML 中获取此实例,使用 x: Static。
您可以获得整个实例,或创建一个绑定到单独的 属性.
<SomeElement
DataContext="{x:Static vm:MainWindowViewModel.Instance}"/>
<SomeElement
Command="{Binding ButtonCommandEvent,
Source={x:Static vm:MainWindowViewModel.Instance}}"/>
我目前面临的问题是我的 DataGrid 绑定没有刷新 UI。 我的 ViewModel 和 Object 继承自 INotifyPropertyChanged。
这是我的代码:
XAML:
<DataGrid Grid.Row="2" DataContext="{StaticResource MainViewModel}" ItemsSource="{Binding TestCollection, Mode=OneWay}" AutoGenerateColumns="True"/>
视图模型:
public class MainViewModel: ViewModelBase
{
private ObservableCollection<ProductDisplayItem> _testCollection;
public ObservableCollection<ProductDisplayItem> TestCollection
{
get => _testCollection;
set => SetProperty(ref _testCollection, value);
}
private async void SendSearch()
{
//MyCode
.....
IEnumerable<ProductDisplayItem> displayItems = DisplayItemHelper.ConvertToDisplayItems(products);
TestCollection = new ObservableCollection<ProductDisplayItem>(displayItems);
}
}
我的对象:
public class ProductDisplayItem: ViewModelBase
{
private string _mfrPartNumber;
private double _unitPrice;
private int _stock;
public string MfrPartNumber
{
get => _mfrPartNumber;
set => SetProperty(ref _mfrPartNumber, value);
}
public double UnitPrice
{
get => _unitPrice;
set => SetProperty(ref _unitPrice, value);
}
public int Stock
{
get => _stock;
set => SetProperty(ref _stock , value);
}
public ProductDisplayItem()
{
}
public ProductDisplayItem(string mfrp, double unitPrice, int stock)
{
MfrPartNumber = mfrp;
UnitPrice = unitPrice;
Stock = stock;
}
}
还有我的 ViewModelBase:
public abstract class ViewModelBase: IDisposable, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = "")
{
if (EqualityComparer<T>.Default.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
public void Dispose()
{
}
}
我也尝试将项目添加到 ObservableCollection 而不是创建一个新项目,但结果相同。 我希望任何人都可以帮助我。
提前致谢
好的,我明白了。这是数据上下文... 从 xaml.
中删除后工作正常此类错误的最常见原因是对 ViewModel 实例的混淆:UI 元素绑定到一个实例,而您正在修改另一个实例中的集合。
由于 WPF MVVM 通常只提供在一个实例中使用主 ViewModel,请尝试使用 Singleton。
有类似问题的新主题:
那里的第一个实施选项:
1) 如果:
- 一般来说,原则上,在任何情况下都不会假设一个 ViewModel 在创建它的程序集级别上可以有多个实例;
- 如果这不会造成任何安全问题,因为每个人都可以访问静态实例;
- 如果静态值足以创建单个实例。在大多数情况下,这意味着 ViewModel 只有一个非参数化构造函数。
那么在这种情况下,使用单例是值得的。
示例:
public class MainWindowViewModel : ViewModelBase
{
// The only instance available outside of this class.
public static MainWindowViewModel Instanse { get; }
= new MainWindowViewModel();
// All constructors must be MANDATORY HIDDEN.
private MainWindowViewModel()
{
// Some code
}
// Some code
}
要在 XAML 中获取此实例,使用 x: Static。
您可以获得整个实例,或创建一个绑定到单独的 属性.
<SomeElement
DataContext="{x:Static vm:MainWindowViewModel.Instance}"/>
<SomeElement
Command="{Binding ButtonCommandEvent,
Source={x:Static vm:MainWindowViewModel.Instance}}"/>