2011-12-18 55 views
1

我的情況的一個行摘要:當我選擇一個細節項時,主仍然是未選中的,所以我得到錯誤的細節項。類似WPF Explorer的MVVM ListBox-in-ListBox(主 - 細節)綁定表達式

假設兩個ViewModel MasterList和DetailList都是ObservableCollection,並且試圖製作類似於Explorer的GUI。左側面板具有主詳細信息列表框,右側面板顯示所選詳細信息項目中的一個。沒有必要在右側顯示主要信息。

在我的左側面板中,ListBox控件編碼如下。

<ListBox x:Name="listBoxMaster" ItemsSource="{Binding Path=MasterList}" SelectionMode="Extended" 
      IsSynchronizedWithCurrentItem="True"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <ListBox x:Name="listBoxDetail" ItemsSource="{Binding Path=DetailList}" IsSynchronizedWithCurrentItem="True" /> 
     </DataTemplate> 
</ListBox.ItemTemplate> 

注意,我設置IsSynchronizedWithCurrentItem = 「true」 以兩個列表框控件。

在右側面板中,選定的詳細項目信息將顯示如下的綁定。讓我們簡化DetailItemClass具有Name和Number屬性的詳細項目類。

試驗1

<WrapPanel Name="wrapPanel1" DataContext="{Binding ElementName=listBoxMaster, Path=SelectedItem}"> 
    <StackPanel DataContext="{Binding Path="DetailList/"> 
     <TextBox Text="{Binding Path=Name}" /> 
     <TextBox Text="{Binding Path=Number}" /> 
    </StackPanel> 
</WrapPanel> 

的weired GUI問題happend。 如果我們有。

  • Master1有詳細的1,2,3。
  • Master2有詳細資料4,5,6。

當我選擇M1-D2時,它工作。 之後,當我選擇細節M2-D4時,它可以工作。 但之後,當我再次選擇M1-D2時,它不起作用!預先選擇的項目可能不會更新其主控選擇。 此外,有時M2-D5的選擇會在右側顯示M1-D2。 weired。

試驗2

<WrapPanel Name="wrapPanel1" DataContext="{Binding Path=MasterList/DetailList/}"> 
    <StackPanel> 
     <TextBox Text="{Binding Path=Name}" /> 
     <TextBox Text="{Binding Path=Number}" /> 
    </StackPanel> 
</WrapPanel> 

只是沒有作品。儘管我將IsSynchronizedWithCurrentItem設置爲true,但失敗。我不知道爲什麼。

試驗3

我剛剛擺脫DataContext的XAML綁定,並在後臺代碼如下使用事件觸發。

private void listBoxMaster_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (e.AddedItems.Count == 1) 
     { 
      if (e.AddedItems[0] is DetailItemClass) 
      { 
       var element = (DetailItemClass)e.AddedItems[0]; 
       wrapPanel1.DataContext = element; 
      } 
     } 
    } 

它工作得很好,但它不使用XAML綁定。

你能教我適當的結合表達嗎?

+1

?這並不酷,不會工作。有這種情況下的TreeView控件。 – vorrtex 2011-12-18 16:17:49

+0

最後我用TreeView控件解決了。 – Youngjae 2012-08-21 05:06:06

回答

0

你嘗試:

<WrapPanel Name="wrapPanel1" DataContext="{Binding ElementName=listBoxMaster, Path=SelectedItem}"> 
    <StackPanel> 
     <TextBox Text="{Binding Path=DetailList.Name}" /> 
     <TextBox Text="{Binding Path=DetailList.Number}" /> 
    </StackPanel> 
</WrapPanel> 

<WrapPanel Name="wrapPanel1"> 
    <StackPanel> 
     <TextBox Text="{Binding ElementName=listBoxMaster, Path=SelectedItem.DetailList.Name}" /> 
     <TextBox Text="{Binding ElementName=listBoxMaster, Path=SelectedItem.DetailList.Number}" /> 
    </StackPanel> 
</WrapPanel> 

這些都是確保在DataContext是否真正級聯。

+0

不,它沒有工作。點運算符是否帶有DetailList(DetailItemClass的ObservableCollection)是否正確?我嘗試了你的建議和DetailList/Name,但是這兩個表達式都不起作用。 – Youngjae 2011-12-18 15:59:25

+0

是的,由於SelectedItem已經在它表示的項目的上下文中,所以點正常工作。所以,數據類型實際上與列表項相同。 – Xcalibur37 2011-12-18 16:21:36

+0

爲了更好地解決這個問題,你能否將你的項目發佈到某個地方,以便我們看到整個畫面? – Xcalibur37 2011-12-18 16:22:13

0

您不應該使用多個列表框,因爲會出現許多與多重選擇相關的問題。例如,您可以選擇第一個列表框,但選擇第二個列表框。

multiple list boxes fail

ItemsControl類更換外部列表框,以便它不接受的選擇,而不是可聚焦。

還將單個屬性添加到包含所有列表的單個選定項目的根模型。我用非常簡單的模型,在這個例子轉載您的層次結構中此屬性被稱爲SelectedDetailItem

public class MasterListViewModel : INotifyPropertyChanged 
{ 
    public ObservableCollection<DetailListViewModel> MasterList { get; set; } 

    private ItemViewModel _selectedDetailItem; 

    public ItemViewModel SelectedDetailItem 
    { 
     get { return _selectedDetailItem; } 
     set 
     { 
      _selectedDetailItem = value; 
      OnPropertyChanged("SelectedDetailItem"); 
     } 
    } 
} 

public class DetailListViewModel 
{ 
    public ObservableCollection<ItemViewModel> DetailList { get; set; } 
} 

public class ItemViewModel 
{ 
    public string Title { get; set; } 
} 

而這個屬性綁定到兩個控件:你爲什麼要使用列表框的列表框

<ItemsControl x:Name="listBoxMaster" ItemsSource="{Binding Path=MasterList}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <ListBox x:Name="listBoxDetail" ItemsSource="{Binding Path=DetailList}" DisplayMemberPath="Title" 
         SelectedItem="{Binding DataContext.SelectedDetailItem, Mode=TwoWay, ElementName=listBoxMaster}"/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

<WrapPanel Name="wrapPanel1" DataContext="{Binding SelectedDetailItem}" Grid.Column="1"> 
    <TextBox Text="{Binding Path=Title}" /> 
</WrapPanel> 
+0

感謝您的回答。我發現ItemsControl沒有用於多選的SelectionMode屬性。有什麼辦法可以做出多個主列表的選擇?因爲我需要讓用戶可以選擇多個主項目以刪除或移動到某個地方。 (或TreeView控件作爲您的推薦可能是最好的?) – Youngjae 2011-12-18 17:14:03

+0

@Youngjae有沒有簡單的方法來使用數據綁定多個選擇:http://stackoverflow.com/questions/2511708/databinding-a-listbox-with -selectionmode海報。所以它需要很多代碼才能正確實現。 – vorrtex 2011-12-18 19:52:37

+0

@Youngjae順便說一下,Windows資源管理器不允許在左側面板上選擇多個項目。 – vorrtex 2011-12-18 19:53:49