WPF MVVM 可观察集合未正确更新 GUI



我正在尝试创建一个应用程序,您可以在其中选择一道菜,它会自动添加到您的订单中。

因此,我使用包含订单中的菜肴的ListView制作了此 XAML 代码。每当添加菜肴时,它都应该自动更新(带有RelayCommand)。

<UserControl.DataContext>
<viewn:ViewModelOrder/>
</UserControl.DataContext>
<ListView x:Name="CommandListView" ItemsSource="{Binding Order}" >
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name_Dish}"/>
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding Price_Dish}" />
</GridView>
</ListView.View>
</ListView>

下面您可以看到绑定到ListView的订单ObservableCollection

public class ViewModelOrder : ViewModelBase, INotifyPropertyChanged
{
private ObservableCollection<Dish> _Order;    
public ObservableCollection<Dish> Order
{
get { return _Order; }
set
{
_Order = value;
OnPropertyChanged("Order");
}
}
}

真正奇怪的是,业务逻辑按预期工作(订单ObservableCollection充满了菜肴),但是这些更改没有显示在ListView上。

更奇怪的是,当应用程序运行时,我在绑定的末尾添加一个点,所以它看起来像这样:ItemsSource="{Binding Order.}",UI 完全按预期更新(它显示之前添加的所有菜肴,并在我添加另一个菜肴时更新)。所以我不太确定是什么导致了这个问题。

你知道可能是什么问题吗?

更新

我的 XAML 中的绑定似乎存在问题。实际上,输出窗口显示以下错误:

System.Windows.Data Error: 40 : BindingExpression path error: 'AddDishToOrder' property not found on 'object' ''Dish_801880DFD6EB7B0C17C1467B62FCB73FB779084FCF737D81239B8934238C3474' (HashCode=45081147)'. BindingExpression:Path=AddDishToOrder; DataItem='Dish_801880DFD6EB7B0C17C1467B62FCB73FB779084FCF737D81239B8934238C3474' (HashCode=45081147); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand')

此错误在为所有菜肴生成的此按钮上引发:

<ItemsControl Name="DishesItemsControl" ItemsSource="{Binding Dishes}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding AddDishToOrder}">
<Button.DataContext>
<viewn:ViewModelOrder/>
</Button.DataContext>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>

绑定正在调用此方法:

private RelayCommand _addDishToOrder;
public RelayCommand AddDishToOrder
{
get
{
if (_addDishToOrder == null)
{
//The DoAddDish method simply add the dish to the ObservableCollection
_addDishToOrder = new RelayCommand<object>(DoAddDish);
}
return _addDishToOrder;
}
set { _addDishToOrder = value; }
}

如果我理解正确,错误来自用于将菜肴添加到订单中的按钮。但是我不能完全理解它们有什么问题,因为在调试时正确调用了该方法。

尝试在绑定中添加"path"关键字,如下所示:

<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name_Dish}"/>

正如@XAMIMAX指出的那样,我的Button里有一个完全错误的DataContext。所以,我将按钮的代码更改为这样的东西,现在它完全可以工作了:

<Button Command="{Binding AddDishToOrder}" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext}"/>

如果我正确理解您的问题,则不应将_Order包装为属性,而应仅使用:

public class ViewModelOrder : ViewModelBase, INotifyPropertyChanged
{   
public ObservableCollection<Dish> Order{get;set;}
}

最新更新