2014-09-05 16 views
0

我試圖創建一個具有擴展的列表視圖中的兩個不同的項目來源,我希望當我按下擴大他們中的一個,從不同的項目源名稱的列表被載入。到目前爲止,我得到的是,當我設置的項目源LineRouteCollection設置擴展的頭部,即使我綁定擴展顯示來自AllStopsCollection結合「名」的名稱顯示從LineRouteCollection源的名稱,而不是名稱來自AllStopsCollection,因爲我想要的。你能看看我的代碼,並告訴我我做錯了什麼嗎?Catel MVVM如何設置一個列表框

<ListBox> 
    <ItemsControl ItemsSource="{Binding LineRouteCollection}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Expander Header="{Binding Name}" MinHeight="70">        
        <ListBox > 
         <ItemsControl ItemsSource ="{Binding AllStopsCollection}"> 
          <TextBlock Text="{Binding Name}"></TextBlock> 
         </ItemsControl> 
        </ListBox> 
       </Expander> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 
</ListBox> 

編輯:

在我的視圖模型我加載觀察集合(AllStopsCollection & LineRouteCollection)是這樣的:

private ObservableCollection<Route> AllLineRoutes; 
private ObservableCollection<StopView> AllRouteStops; 

//List of all Routes connected to the selected line 
public ObservableCollection<Route> LineRouteCollection // Must be property or DP to be bound! 
{ 
    get { return AllLineRoutes; } 
    set 
    { 
     if (Equals(value, AllLineRoutes)) return; 
     AllLineRoutes = value; 
    } 
} 


//List of all stops 
public ObservableCollection<StopView> AllStopsCollection // Must be property or DP to be bound! 
{ 
    get { return AllRouteStops; } 
    set 
    { 
     if (Equals(value, AllRouteStops)) return; 
     AllRouteStops = value; 
    } 
} 

而且我填的數據集合中的類的構造函數。我正確加載數據,我可以看到它,但它只是在擴展器展開後纔會出現在文本框中。

+0

這裏的問題是您需要提供'ItemTemplate'而不是嵌套文本框而不是'ItemsControl'。你應該有一個與ItemsControl內部的ItemsControl中的第一個'ItemsControl'相同的設置,其中包含文本塊的ItemsControl.ItemTemplate',否則文本塊的綁定範圍就是第一個'DataTemplate'的綁定範圍 – Charleh 2014-09-05 12:01:25

+0

我已經更新了我的答案 - 你的問題是綁定範圍(我希望你有一個模型數據的層次結構而不是兩個平面集合) – Charleh 2014-09-08 11:12:02

回答

1

您提供了一個ItemTemplate的第ItemsControl,但內ItemsControl包含只是嵌套在控制

您需要爲內部控制過於

<ListBox> 
    <ItemsControl ItemsSource="{Binding LineRouteCollection}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Expander Header="{Binding Name}" MinHeight="70">        
        <ListBox> 
         <ItemsControl ItemsSource ="{Binding AllStopsCollection}"> 
          <ItemsControl.ItemTemplate> <!-- You forgot this ItemTemplate --> 
           <DataTemplate> 
            <TextBlock Text="{Binding Name}"></TextBlock> 
           </DataTemplate> 
          </ItemsControl.ItemTemplate> 
         </ItemsControl> 
        </ListBox> 
       </Expander> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 
</ListBox> 

指定ItemTemplate否則綁定範圍爲最內側TextBlock是要內TextBlock與內部相同ItemsControl導致您正在看到的問題

不確定爲什麼您在ListBox內有ItemsControl雖然..?你想多Expanders一個ListBox而不是單一的列表項裏面?

這爲我一個人工作得很好:

<ListBox ItemsSource="{Binding LineRoutes}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <Expander Header="{Binding Name}" MinHeight="70"> 
        <ListBox ItemsSource ="{Binding AllStops}"> 
          <ListBox.ItemTemplate> 
           <!-- You forgot this ItemTemplate --> 
           <DataTemplate> 
            <TextBlock Text="{Binding Name}"></TextBlock> 
           </DataTemplate> 
          </ListBox.ItemTemplate> 
        </ListBox> 
       </Expander> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 

Example of nested expanders in listbox

這是你想要的嗎?

編輯:

確定在更新的光,我可以看到的是什麼錯誤

你要保持你的眼睛去皮在輸出窗口綁定錯誤。

AllStopsCollection不是內部控制指向一個Route不是ViewModelLineRouteCollection所以DataContext一個孩子。

爲了綁定到Stop的集合,您需要確保將綁定指向具有ViewModel的控件,因爲它的DataContext。最簡單的方法是使用ElementName結合並與根對照(通常稱爲LayoutRoot

例如

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:wpfApplication1="clr-namespace:WpfApplication1" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525" d:DataContext="{d:DesignInstance wpfApplication1:ViewModel}"> 
    <Grid Name="LayoutRoot"> 
     <ListBox ItemsSource="{Binding LineRouteCollection}"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Expander Header="{Binding Name}" MinHeight="70"> 
         <ListBox ItemsSource ="{Binding DataContext.AllStopsCollection, ElementName=LayoutRoot}"> <!-- Provide an ElementName binding to point to the root Grid and bind to the viewmodels AllStopsCollection (viewmodel is in the DataContext) --> 
          <ItemsControl.ItemTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Name}"></TextBlock> 
           </DataTemplate> 
          </ItemsControl.ItemTemplate> 
         </ListBox> 
        </Expander> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </Grid> 
</Window> 

希望幫助

唯一需要注意的是,如果你需要操縱一站 - 很明顯,因爲你要綁定同一個集合到多個子列表,如果你改變一個Stop項目它將會更改每個列表中的值,因爲參考都指向相同的對象

+0

嗯,我認爲你是正確的ItemTemplate,但現在,我已經修復它的問題仍然存在,現在它不顯示任何東西。但我認爲你把我放在正確的軌道上 – user3182266 2014-09-05 12:16:06

+0

可能與你所擁有的控件的嵌套有關 - 我會看看我是否可以生成一個例子 – Charleh 2014-09-05 12:44:19

+0

好吧,我已經更新了,好像你正試圖嵌套' ItemsControl裏面的控件 - 一個ListBox *是一個ItemsControl,所以你不需要嵌套在ListBox裏面。我假設你想要兩個列表框,一個嵌套在另一個不同的項目源內 – Charleh 2014-09-05 12:52:10

-1

也就是一種方法,嘗試更加動感。這是一個列表框,其中我有預定義的3個不同的文本框,並在運行時提供值。

<ListBox x:Name="ListBox1" HorizontalAlignment="Left" Height="253" Margin="10,28,0,0" VerticalAlignment="Top" Width="734"> 
        <ListBox.ItemTemplate> 
         <DataTemplate> 
          <Grid x:Name="grid" Margin="0,2"> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="*" /> 
            <ColumnDefinition Width="234" /> 
            <ColumnDefinition Width="143" /> 
           </Grid.ColumnDefinitions> 
           <TextBlock Grid.Column="0" HorizontalAlignment="Left" Text="{Binding String1}"/> 
           <TextBlock Grid.Column="1" HorizontalAlignment="Left" Text="{Binding String2}" TextTrimming="WordEllipsis"/> 
           <TextBlock Grid.Column="2" HorizontalAlignment="Left" Text="{Binding String3}"/> 
          </Grid> 
         </DataTemplate> 
        </ListBox.ItemTemplate> 
       </ListBox> 

代碼背後:

public class Class1 
    { 
     public string String1 { get; set; } 
     public string String2 { get; set; } 
     public string String3 { get; set; } 
    } 

    private void Button1_Click(object sender, RoutedEventArgs e) 
    { 
      ListBox1.Items.Add((new Class1() 
      { 
       String1 = "Apple", 
       String2 = "Car", 
       String3 = "Tree" 
      })); 
    } 

OR

如果你想一個解決方案,在運行時更加動態,你可以做這樣的事情:

private void Button1_Click(object sender, RoutedEventArgs e) 
    { 
       Grid WholeGrid = new Grid(); 
       WholeGrid.HorizontalAlignment = HorizontalAlignment.Left; 
       ColumnDefinition colDef1 = new ColumnDefinition(); 
       ColumnDefinition colDef2 = new ColumnDefinition(); 
       ColumnDefinition colDef3 = new ColumnDefinition(); 
       WholeGrid.ColumnDefinitions.Add(colDef1); 
       WholeGrid.ColumnDefinitions.Add(colDef2); 
       WholeGrid.ColumnDefinitions.Add(colDef3); 

       // Create Question Lable 
       Label QuestionLabel = new Label(); 
       QuestionLabel.Content = "Apple"; 
       Grid.SetRow(QuestionLabel, 0); 
       Grid.SetColumn(QuestionLabel, 0); 

       // Create Date Picker 
       DatePicker newDatePicker = new DatePicker(); 
       newDatePicker.Width = 200; 
       newDatePicker.Height = 20; 
       Grid.SetRow(newDatePicker, 0); 
       Grid.SetColumn(newDatePicker, 1); 

       // Add to Lable and Date Picker 
       WholeGrid.Children.Add(QuestionLabel); 
       WholeGrid.Children.Add(newDatePicker); 
       ListBox1.Items.Add(WholeGrid); 
    } 
+0

這不是一個非常MVVM友好的做任何事情的方式,也不會回答OP的問題 – Charleh 2014-09-05 11:56:23