【问题标题】:Observable Collection do not update the UIObservable Collection 不更新 UI
【发布时间】:2018-11-09 01:15:27
【问题描述】:

我正在研究在可观察集合中添加和删除行的能力。 我有 UserControl 视图,其中 ListView 绑定到 ObservableCollection。 我也有删除命令在 ViewModel 中工作,但不更新 UI。

这是我在 ViewModel 上的代码,它继承自 MvvmLight ViewModelBase 类。

 public class ProductInfoViewModel : ViewModelBase
{
    #region Properties

    private ObservableCollection<Product> _productList;
    public ObservableCollection<Product> ProductList
    {
        get { return _productList; }
        set
        {
            _productList =  value;
            RaisePropertyChanged("ProductList");
        }
    }

    #endregion
    #region Constructor
    public ProductInfoViewModel()
    {
        ConnectWebService connect = new ConnectWebService();
        string json = connect.getResponse(@"http://localhost:8082/products");
        ProductList = JsonConvert.DeserializeObject<ObservableCollection<Product>>(json);
        DeleteCommand = new RelayCommand<long>((id) => DeleteCommandHandler(id, ProductList));
    }
    #endregion
    #region Commands
    public ICommand DeleteCommand { get; private set; }
    #endregion
    #region CommandsHandlers
    private void DeleteCommandHandler(long id, ObservableCollection<Product> productList)
    {
        try
        {
            productList.Remove(productList.Where(i => i.ProductId == id).First());

        }
        catch (Exception)
        {
        }
    }

这是我在 XAML 中的代码:

<UserControl.DataContext>
    <local:ProductInfoViewModel/>
</UserControl.DataContext>
<Grid>
    <Grid Margin="0,50,0,100">
        <ListView  Margin="5" SelectionChanged="ListView_SelectionChanged" ItemsSource="{Binding ProductList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="Black" Background="White" BorderBrush="{x:Null}" 
                   x:Name="ProductList">
            <ListView.View>
                <GridView>
                    <GridViewColumn  Header="Kod" Width="50" DisplayMemberBinding="{Binding ProductCode}"/>
                    <GridViewColumn  Header="Nazwa" Width="150" DisplayMemberBinding="{Binding ProductName}" />
                    <GridViewColumn  Header="Typ" Width="150" DisplayMemberBinding="{Binding ProductType}" />
                    <GridViewColumn  Header="Opis" Width="300" DisplayMemberBinding="{Binding ProductDescription}" />
                    <GridViewColumn  Header="Dostępność" Width="150" DisplayMemberBinding="{Binding ProductAvability}" />
                    <GridViewColumn Width="80">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Edytuj" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center"
                                        Click="Button_Click"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Width="80">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Usuń" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center" 
                                        Click="Delete_Click" Command="{Binding ProductInfoView.DeleteCommand, Mode=OneWay, Source={StaticResource Locator}}" CommandParameter="{Binding ProductId}"
                                         />
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>

我的产品类实现了 INotifyPropertyChanged 接口,但我也使用 Fody。

现在,仅当我将视图更改为另一个视图然后返回时,视图才会更新。 我不知道出了什么问题。 如果有任何帮助,我将不胜感激!

【问题讨论】:

  • 附注:ItemsSource 绑定不需要Mode=TwoWay, UpdateSourceTrigger=PropertyChanged。这是没用的,因为ItemsControl 永远不会更改项目源对象引用。
  • DeleteCommandHandler 有 productList 参数似乎很奇怪。它也可以直接对 ProductList 属性进行操作。也就是说,您是否确保它被实际调用,并且传递的 ProductId 是有效的,即没有抛出异常(然后您通过一个空的 catch 块忽略它)?
  • 我删除了 try, catch 块(我使用它,因为当我从列表中删除项目时它仍然出现在 UI 中,并且当我再次点击删除触发器时出现异常)我还更改了 ProductList 属性的 productList 参数直接,但问题仍然存在。

标签: wpf listview mvvm mvvm-light observablecollection


【解决方案1】:

您将ButtonCommand 属性绑定到Locator 资源返回的视图模型。您应该将其绑定到 ListView 绑定到的同一实例:

<DataTemplate>
    <Button Content="Usuń" Background="Transparent" BorderThickness="0" Foreground="Blue" Width="50" Margin="0" HorizontalAlignment="Center" 
            Click="Delete_Click"
            Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=ListView}}" 
            CommandParameter="{Binding ProductId}"/>
</DataTemplate>

【讨论】:

    【解决方案2】:

    当您从列表中删除项目时,您不会使用您的产品列表设置器,因此不会调用 RaisePropertyChanged。快速解决方法是在删除项目后添加对 RaisePropertyChanged 的调用:

    productList.Remove(productList.Where(i => i.ProductId == id).First());
    RaisePropertyChanged("ProductList");
    

    【讨论】:

    • 没必要,因为 productList 是 ObservableCollection。
    猜你喜欢
    • 2021-12-25
    • 2022-01-27
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 2018-06-15
    相关资源
    最近更新 更多