2010-04-01 68 views
2

在Silverlight中,我有以下的ItemsControl 3MVVM在Silverlight3的ItemsControl綁定獲取父控件的DataContext

<ItemsControl ItemsSource="{Binding ValueCollectionList}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 

      <Button x:Name="MyBtn" Height="40" Content="{Binding Name}" 
       Tag="{Binding Value}" 
       cmd:ButtonBaseExtensions.Command="{Binding ElementName=LayoutRoot, Path=ButtonCommand}" 
       cmd:ButtonBaseExtensions.CommandParameter="{Binding ElementName=MyBtn, Path=Tag}"/> 

     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

的問題是,我有綁定到收藏在我的ViewModel ItemsControl的,但我需要的按鈕在ViewModel上觸發一個當然不是按鈕的DataContext中可用的命令,因爲它只包含集合。

我可以通過設置我的ViewModel作爲資源,然後綁定到一個StaticResource,但我想知道爲什麼元素綁定元素不能在這種情況下工作。我寧願不使用StaticResource綁定,因爲這需要ViewModel上的默認構造函數,所以我無法輕鬆注入數據。

UPDATE

我通過這個速度很慢......望着彼得,我意識到,我可能因爲我的頁面設置的更嚴重的綁定問題的建議。我有兩個可能的路障,但首先是第一件事。

上面的My Items控件包含在另一個綁定到可觀察集合的項目控件中。我移動了我的項目控件,以便它的根項目控件的直接子項。它被包裹在另一個控制中,我會到達。所以我嘗試了綁定到項目控件ControlItemList的元素,但是它是一個集合,所以它無法在該集合中找到我的ButtonCommand方法。我需要做的是綁定到該集合中的一個項目。如何綁定到集合中的單個項目?

<Grid x:Name="LayoutRoot" Background="White"><!-- DataContext="{Binding Path=., Source={StaticResource lvvm}}">--> 
    <StackPanel Orientation="Vertical"> 
     <ItemsControl x:Name="ControlItemList" ItemsSource="{Binding}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <Grid> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition MinWidth="100" /> 
          <ColumnDefinition Width="*" /> 
          <ColumnDefinition Width="*"/> 
         </Grid.ColumnDefinitions> 
         <TextBlock x:Name="ControlName" Grid.Column="0" Text="{Binding Name}" VerticalAlignment="Center" /> 
         <ItemsControl ItemsSource="{Binding ValueCollectionList}"> 
          <ItemsControl.ItemTemplate> 
           <DataTemplate> 

因此,假設我能得到上述工作的其他道路塊是我的項目控制被包裹在我使用得到DataTemplateSelector型功能的另一個用戶控件。我認爲這個控件可能阻止我進入父DataContext。你可以走多遠樹有限制嗎?

<common:DeviceControlTemplateSelector Grid.Column="1" FieldType="{Binding ValueType}" Margin="0,2,0,2"> 
          <common:DeviceControlTemplateSelector.StringTemplate> 
           <DataTemplate> 
            <TextBox Text="{Binding Value, Mode=TwoWay}" Width="100"/> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.StringTemplate> 
          <common:DeviceControlTemplateSelector.DateTimeTemplate> 
           <DataTemplate> 
            <TextBox Text="this is date time binding" Width="100"/> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.DateTimeTemplate> 
          <common:DeviceControlTemplateSelector.BooleanTemplate> 
           <DataTemplate> 
            <CheckBox IsChecked="{Binding Value, Mode=TwoWay}" /> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.BooleanTemplate> 
          <common:DeviceControlTemplateSelector.IntegerTemplate> 
           <DataTemplate> 
            <ComboBox ItemsSource="{Binding ValueCollection}" DisplayMemberPath="Value" SelectedIndex="{Binding Value, Mode=TwoWay}" > 

            </ComboBox> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.IntegerTemplate> 
          <common:DeviceControlTemplateSelector.MultiButtonTemplate> 
           <DataTemplate> 
             <ItemsControl ItemsSource="{Binding ValueCollectionList}"> 
              <ItemsControl.ItemTemplate> 
               <DataTemplate> 

                <Button x:Name="MyBtn" 
                  Height="40" Content="{Binding Name}" 
                  Tag="{Binding Value}" 
                  cmd:ButtonBaseExtensions.Command="{Binding ElementName=ControlItemList, Path=DataContext.ButtonCommand}"                
                  cmd:ButtonBaseExtensions.CommandParameter="{Binding Value}"/> 
               </DataTemplate> 
              </ItemsControl.ItemTemplate> 
             </ItemsControl> 
           </DataTemplate> 
          </common:DeviceControlTemplateSelector.MultiButtonTemplate> 

            <Button x:Name="MyBtn" 
                  Height="40" Content="{Binding Name}" 
                  Tag="{Binding Value}" 
                  cmd:ButtonBaseExtensions.Command="{Binding ElementName=ControlItemList, Path=ButtonCommand}"                
                  cmd:ButtonBaseExtensions.CommandParameter="{Binding Value}"/> 
           </DataTemplate> 
          </ItemsControl.ItemTemplate> 
         </ItemsControl> 

再次感謝大家的幫助!

回答

0

在MVVM消息傳遞中,ViewModels之間的通信是一個強大的概念。您可以使用PRISM Eventaggregator或MVVM Light Toolkit的Messenger類。在按鈕命令上,您可以發佈消息並在視圖模型中訂閱它。

+0

謝謝silverfighter的職位,但我真的想知道爲什麼我上面的代碼不起作用。我可能不得不去消息路由或使ViewModel一個靜態資源,但我不明白爲什麼我不能從我的itemscontrol內訪問父對象datacontext。 – BigTundra 2010-04-06 12:52:52

+0

EventAggregator在單個ViewModel中的消息傳遞是否過度(更不用說Module)了? – Pat 2011-01-21 18:08:13

1

嘗試從

CMD改變
:ButtonBaseExtensions.Command = 「{結合的ElementName = LayoutRoot,路徑= ButtonCommand}」

CMD:ButtonBaseExtensions.Command =「{結合的ElementName = LayoutRoot,路徑= DataContext.ButtonCommand}」

OR

cmd:ButtonBaseExtensions.Command =「{Binding ElementName = LayoutRoot.DataContext,Path = ButtonCommand}」

+0

我無法得到這個工作,因爲LayoutRoot的DataContext是一個ObservableCollection,所以當我嘗試綁定到我的ButtonCommand方法時,我得到... System.Windows.Data錯誤:BindingExpression路徑錯誤:'ButtonCommand' 'System.Collections.ObjectModel.ObservableCollection'1 [Chopper.Common.DeviceControlViewModel]''System.Collections.ObjectModel.ObservableCollection'1 [Chopper.Common.DeviceControlViewModel]'(HashCode = 26753075)上找不到屬性。 BindingExpression:Path ='DataContext.ButtonCommand'DataItem ='System.Windows.Controls.ItemsControl' 如何綁定到該項目? – BigTundra 2010-04-13 13:45:36

相關問題