GridView 视觉上不显示 BindingList 中的新数据
GridView visually not showing new data in BindingList
我不熟悉将 MVVM 与 WPF 结合使用,但遇到了障碍。我有一个 BindingList
绑定到 GridView
上的 ItemsSource
。我添加了一个按钮,它使用 RelayCommand
从数据库中提取新数据并将其存储在 BindingList
中。调试时我可以在 BindingList
中看到新项目,但在视觉上它没有显示在网格中。这让我很吃力,请看下面我的代码块:
这是对网格视图的绑定:
ItemsSource="{Binding ListOfAllShipments, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedShipment}"
这是视图模型:
public class EntriesShipmentViewModel : INotifyPropertyChanged
{
public EntriesShipmentViewModel()
{
GetAllShipments();
RefreshGridViewsCommand = new RelayCommand(GetAllShipments);
}
private BindingList<Shipment> _listOfAllShipments;
private BindingList<Shipment> _listOfAssignedShipments;
#region Private Properties
private Shipment _selectedShipment;
private string _manifestNumber;
private string _carrier;
private string _localShippingAgent;
private string _voyageNumber;
private string _shipmentKey;
#endregion
#region Public Properties
public Shipment SelectedShipment
{
get => _selectedShipment;
set
{
if (value == null)
return;
_selectedShipment = value;
OnPropertyRaised(SelectedShipment.ToString());
PopulateManifestInformation(SelectedShipment);
}
}
public string ManifestNumber
{
get => _manifestNumber;
set
{
_manifestNumber = value;
OnPropertyRaised(ManifestNumber);
OnPropertyRaised(nameof(ManifestNumber));
}
}
public string Carrier
{
get => _carrier;
set
{
_carrier = value;
OnPropertyRaised(Carrier);
OnPropertyRaised(nameof(Carrier));
}
}
public string LocalShippingAgent
{
get => _localShippingAgent;
set
{
_localShippingAgent = value;
OnPropertyRaised(LocalShippingAgent);
OnPropertyRaised(nameof(LocalShippingAgent));
}
}
public string VoyageNumber
{
get => _voyageNumber;
set
{
_voyageNumber = value;
OnPropertyRaised(VoyageNumber);
OnPropertyRaised(nameof(VoyageNumber));
}
}
public string ShipmentKey
{
get => _shipmentKey;
set
{
_shipmentKey = value;
OnPropertyRaised(ShipmentKey);
OnPropertyRaised(nameof(ShipmentKey));
}
}
#endregion
public ICommand RefreshGridViewsCommand { get; }
private void GetAllShipments()
{
ListOfAllShipments = ShipmentViewModel.GetAllShipments();
if (SelectedShipment != null)
{
SelectedShipment = null;
}
}
public BindingList<Shipment> ListOfAllShipments
{
get => _listOfAllShipments;
set
{
_listOfAllShipments = value;
}
}
private void PopulateManifestInformation(Shipment shipment)
{
if (shipment == null)
return;
if (shipment.MasterManifest != null)
{
ManifestNumber = shipment.MasterManifest.Number;
if (shipment.MasterManifest.IsMasterManifest && shipment.MasterManifest.Voyage != null)
{
Carrier = shipment.MasterManifest.Voyage.Carrier.Name;
LocalShippingAgent = shipment.MasterManifest.LocalShippingAgent.Name;
VoyageNumber = shipment.MasterManifest.Voyage.DisplayName;
}
}
else if (shipment.SupplementaryManifest != null)
{
ManifestNumber = shipment.SupplementaryManifest.Number;
if (shipment.SupplementaryManifest.IsMasterManifest && shipment.SupplementaryManifest.Voyage != null)
{
Carrier = shipment.SupplementaryManifest.Voyage.Carrier.Name;
LocalShippingAgent = shipment.SupplementaryManifest.LocalShippingAgent.Name;
VoyageNumber = shipment.SupplementaryManifest.Voyage.DisplayName;
}
}
ShipmentKey = shipment.Id.ToString();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyRaised(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
}
}
问题是您创建了一个新集合并将其分配给 ListOfAllShipments
属性:
ListOfAllShipments = ShipmentViewModel.GetAllShipments();
但是,您没有在 setter 中引发 PropertyChanged
事件,因此绑定不会更新。
public BindingList<Shipment> ListOfAllShipments
{
get => _listOfAllShipments;
set
{
_listOfAllShipments = value;
OnPropertyRaised(nameof(ListOfAllShipments));
}
}
另一种方法是始终使用相同的集合,但只需在 GetAllShipments
方法中使用 Clear()
or ClearItems()
清除它并添加新项目。 BindingList
.
会自动通知这些更改
为了完整起见,对您的代码进行一些说明。
您可以从 ItemsSource
绑定中删除 UpdateSourceTrigger
。
OnPropertyRaised
调用得到一个 属性 name 作为参数,所以像这样使用 nameof
是可以的:
OnPropertyRaised(nameof(ShipmentKey));
但是,我认为像下面这样的重复调用没有意义,因为您传递了 属性 值 。因此,您应该能够毫无区别地删除它们。
PropertyRaised(ShipmentKey);
我不熟悉将 MVVM 与 WPF 结合使用,但遇到了障碍。我有一个 BindingList
绑定到 GridView
上的 ItemsSource
。我添加了一个按钮,它使用 RelayCommand
从数据库中提取新数据并将其存储在 BindingList
中。调试时我可以在 BindingList
中看到新项目,但在视觉上它没有显示在网格中。这让我很吃力,请看下面我的代码块:
这是对网格视图的绑定:
ItemsSource="{Binding ListOfAllShipments, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedShipment}"
这是视图模型:
public class EntriesShipmentViewModel : INotifyPropertyChanged
{
public EntriesShipmentViewModel()
{
GetAllShipments();
RefreshGridViewsCommand = new RelayCommand(GetAllShipments);
}
private BindingList<Shipment> _listOfAllShipments;
private BindingList<Shipment> _listOfAssignedShipments;
#region Private Properties
private Shipment _selectedShipment;
private string _manifestNumber;
private string _carrier;
private string _localShippingAgent;
private string _voyageNumber;
private string _shipmentKey;
#endregion
#region Public Properties
public Shipment SelectedShipment
{
get => _selectedShipment;
set
{
if (value == null)
return;
_selectedShipment = value;
OnPropertyRaised(SelectedShipment.ToString());
PopulateManifestInformation(SelectedShipment);
}
}
public string ManifestNumber
{
get => _manifestNumber;
set
{
_manifestNumber = value;
OnPropertyRaised(ManifestNumber);
OnPropertyRaised(nameof(ManifestNumber));
}
}
public string Carrier
{
get => _carrier;
set
{
_carrier = value;
OnPropertyRaised(Carrier);
OnPropertyRaised(nameof(Carrier));
}
}
public string LocalShippingAgent
{
get => _localShippingAgent;
set
{
_localShippingAgent = value;
OnPropertyRaised(LocalShippingAgent);
OnPropertyRaised(nameof(LocalShippingAgent));
}
}
public string VoyageNumber
{
get => _voyageNumber;
set
{
_voyageNumber = value;
OnPropertyRaised(VoyageNumber);
OnPropertyRaised(nameof(VoyageNumber));
}
}
public string ShipmentKey
{
get => _shipmentKey;
set
{
_shipmentKey = value;
OnPropertyRaised(ShipmentKey);
OnPropertyRaised(nameof(ShipmentKey));
}
}
#endregion
public ICommand RefreshGridViewsCommand { get; }
private void GetAllShipments()
{
ListOfAllShipments = ShipmentViewModel.GetAllShipments();
if (SelectedShipment != null)
{
SelectedShipment = null;
}
}
public BindingList<Shipment> ListOfAllShipments
{
get => _listOfAllShipments;
set
{
_listOfAllShipments = value;
}
}
private void PopulateManifestInformation(Shipment shipment)
{
if (shipment == null)
return;
if (shipment.MasterManifest != null)
{
ManifestNumber = shipment.MasterManifest.Number;
if (shipment.MasterManifest.IsMasterManifest && shipment.MasterManifest.Voyage != null)
{
Carrier = shipment.MasterManifest.Voyage.Carrier.Name;
LocalShippingAgent = shipment.MasterManifest.LocalShippingAgent.Name;
VoyageNumber = shipment.MasterManifest.Voyage.DisplayName;
}
}
else if (shipment.SupplementaryManifest != null)
{
ManifestNumber = shipment.SupplementaryManifest.Number;
if (shipment.SupplementaryManifest.IsMasterManifest && shipment.SupplementaryManifest.Voyage != null)
{
Carrier = shipment.SupplementaryManifest.Voyage.Carrier.Name;
LocalShippingAgent = shipment.SupplementaryManifest.LocalShippingAgent.Name;
VoyageNumber = shipment.SupplementaryManifest.Voyage.DisplayName;
}
}
ShipmentKey = shipment.Id.ToString();
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyRaised(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
}
}
问题是您创建了一个新集合并将其分配给 ListOfAllShipments
属性:
ListOfAllShipments = ShipmentViewModel.GetAllShipments();
但是,您没有在 setter 中引发 PropertyChanged
事件,因此绑定不会更新。
public BindingList<Shipment> ListOfAllShipments
{
get => _listOfAllShipments;
set
{
_listOfAllShipments = value;
OnPropertyRaised(nameof(ListOfAllShipments));
}
}
另一种方法是始终使用相同的集合,但只需在 GetAllShipments
方法中使用 Clear()
or ClearItems()
清除它并添加新项目。 BindingList
.
为了完整起见,对您的代码进行一些说明。
您可以从
ItemsSource
绑定中删除UpdateSourceTrigger
。OnPropertyRaised
调用得到一个 属性 name 作为参数,所以像这样使用nameof
是可以的:OnPropertyRaised(nameof(ShipmentKey));
但是,我认为像下面这样的重复调用没有意义,因为您传递了 属性 值 。因此,您应该能够毫无区别地删除它们。
PropertyRaised(ShipmentKey);