WPF MVVM Observable Collection无法正确更新GUI

时间:2018-01-05 13:32:46

标签: c# wpf listview mvvm data-binding

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

所以我用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>

您可以在下面看到与ObservableCollection

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

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

更奇怪的是,当应用程序运行时我在Binding的末尾添加一个点,所以看起来像这样: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; }
}

如果我理解正确,则错误来自用于向订单添加菜肴的按钮。但我无法完全理解它们的错误,因为我在调试时正确调用了该方法。

3 个答案:

答案 0 :(得分:0)

尝试添加&#34;路径&#34;绑定中的关键字如下:

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:-4)

如果我正确理解你的问题,你不应该通过属性包装_Order,你应该只使用:

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