簡體   English   中英

無法更新子項列表框

[英]Cannot update subitems ListBox

我有兩個ListBox 一個ListBox顯示一些項目。 每個項目都有一個子項目列表。 第二個ListBox顯示第一個ListBox中當前項的子項。 典型的項目/子項目場景。 當我向子項列表添加一個值時,我無法讓第二個ListBox更新。 如何強制第二個ListBox更新我的子項?

我的簡化 XAML 和視圖 model 如下。 請注意,我的觀點 model 繼承自 Prism 的BindableBase 在我看來 model 我有一種方法可以將值添加到子項列表並使用RaisePropertyChanged更新Items屬性。

<ListBox Name="Items" ItemsSource="{Binding Items}" >
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    <ListBox.ItemTemplate>
        <DataTemplate>            
                <Label Content="{Binding ItemValue, Mode=TwoWay}" />            
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

<ListBox Name="SubItems" ItemsSource="{Binding Items.CurrentItem.SubItems}" >
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>

    <ListBox.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
class Item
{
    public int ItemValue { get; set; }
    public List<int> SubItems { get; set; }
}

class MyViewModel : BindableBase
{
    private ObservableCollection<Item> _items = new ObservableCollection<Item>();        

    public MyViewModel()
    {
        List<Item> myItems = new List<Item>() {  /* a bunch of items */ };

        _items = new ObservableCollection<Item>(myItems);
        Items = new ListCollectionView(_items);
    }

    public ICollectionView Items { get; private set; }

    private void AddNewSubItem(object obj)
    {
        Item currentItem = Items.CurrentItem as Item;

        currentItem.SubItems.Add(123);            

        RaisePropertyChanged("Items");
    }
}
class Item
{
    public int ItemValue { get; set; }
    public ObservableCollection<int> SubItems { get;}
      = new ObservableCollection<int>();
}
class MyViewModel : BindableBase
{
    publc ObservableCollection<Item> Items {get;}
        = new ObservableCollection<Item>();        

    public MyViewModel()
    {
        List<Item> myItems = new List<Item>() {  /* a bunch of items */ };

        myItems.ForEach(item => Items.Add(item));
    }

    private Item _currentItem;
    private Item CurrentItem
    {
       get => _currentItem;
       set
       {
          if(Equals(_currentItem, value))
            return;

          _currentItem = value;
          RaisePropertyChanged(nameof(CurrentItem));
       }
    }

    private void AddNewSubItem(object obj)
    {
        CurrentItem.SubItems.Add(123);            
    }
}
<ListBox ItemsSource="{Binding Items}" 
         SelectedItem="{Binding CurrentItem}">
  ********
  ********
</ListBox>

<ListBox ItemsSource="{Binding CurrentItem.SubItems}" >
  ********
  ********
</ListBox>

問題是您的Item類型包含一個List<int> ,它不會通知集合更改,因為它沒有實現INotifyCollectionChanged接口。 因此,當集合被修改時,綁定不會在用戶界面中收到更新其值的通知。 使用實現此接口的集合,例如ObservableCollection<int>將解決該問題。

順便說一句,這同樣適用於ItemValueSubItems屬性以及INotifyPropertyChanged 這兩個屬性都有設置器,這意味着它們可以被重新分配,但綁定也不會得到通知。 由於您使用BindableBase ,因此您可以使用帶有支持字段的SetProperty方法在設置屬性時自動引發PropertyChanged事件。

public class Item : BindableBase
{
   private int _itemValue;
   private ObservableCollection<int> _subItems;

   public int ItemValue
   {
      get => _itemValue;
      set => SetProperty(ref _itemValue, value);
   }

   public ObservableCollection<int> SubItems
   {
      get => _subItems;
      set => SetProperty(ref _subItems, value);
   }
}

關於您的項目的評論。 您嘗試做的是分層數據的主從視圖 由於您已經公開了ICollectionView ,因此您不必顯式使用CurrentItem

當源是集合視圖時,可以用斜杠 (/) 指定當前項。 例如,子句 Path=/ 將綁定設置為視圖中的當前項。 當源是集合時,此語法指定默認集合視圖的當前項。

有一種特殊的綁定語法,您可以在其中使用/來指示當前項,例如:

<ListBox Grid.Row="1" Name="SubItems" ItemsSource="{Binding Items/SubItems}">

另外,關於您查看 model 代碼的一些評論。

  • _items字段初始值設定項是無用的,因為無論如何您都在構造函數中重新分配了該字段。
  • 如果只使用集合視圖而不使用_items ,則可以在構造函數中使用局部變量。
  • 不使用Items的私有 setter,您可以將其移除。
  • Items.CurrentItem直接轉換為Item以獲得一個無效的轉換異常,該異常比 null 引用異常更具體,您稍后在訪問使用as和獲取null的值時會得到該異常。 如果您希望該值可能不是Item ,您可以在as之后檢查null或使用模式匹配來適當地處理成功和錯誤這兩種情況( CurrentItem不是Item類型)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM