2013-06-07 3 views
7

Я запускаю простой проект MVVM и упал в первый барьер. Я связываю свои команды с помощью подхода Josh Smiths Relay Command.Невозможно связать в словаре ресурсов

Проблема в том, что кнопка не является обязательной, когда кнопка находится в ResourceDictionary. Если я переведу код (точно так же, как есть) в свой MainWindow.xaml, тогда код будет выполняться по желанию.

Это мой MainWindow.xaml

<Window x:Class="ForJon.Views.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:vm="clr-namespace:ForJon.Ui.ViewModels" 
    Title="MainWindow" Height="350" Width="525"> 
    <Grid> 

    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="160" /> 
     <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 

    <Grid.Resources> 
     <ResourceDictionary Source="Resources\ResourceDictionary.xaml" /> 
    </Grid.Resources> 

    <Grid.DataContext> 
     <vm:MainWindowViewModel /> 
    </Grid.DataContext> 

    <HeaderedContentControl 
     Header="Options" 
     Style="{StaticResource LeftMenu}" 
     Grid.Column="0" 
     /> 

    </Grid> 
</Window> 

И словарь ресурс

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:view="clr-namespace:ForJon.Ui.Views" 
        xmlns:viewModel="clr-namespace:ForJon.Ui.ViewModels" 
        > 

    <Style x:Key="LeftMenu" TargetType="HeaderedContentControl"> 
     <Setter Property="HeaderTemplate"> 
      <Setter.Value> 
       <DataTemplate> 
         <StackPanel> 
          <Button Content="Add" Command="{Binding AddCommand}" /> 
         </StackPanel> 
       </DataTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Width" Value="160"/> 
    </Style> 

</ResourceDictionary> 

Я могу только предположить, что при связывании в ResourceDictionary, что он не может найти ViewModel (хотя я дон Я не знаю, почему я так думаю. Я думаю, что он пытается связать дополнительный уровень вниз ...

В любом случае, может кто-нибудь объяснить, почему он не выполняется из Словаря ресурсов, пожалуйста.

ответ

8

Эта проблема, кажется, не так много сделать с ResourceDictionary, чем иметь пропуск родительского DataContext к DataTemplate

При копировании Style и поместить его в Grid.Resources и комментарии к словарю ресурс такое же поведение может быть видел. Также включение Binding ошибок должны показать

System.Windows.Data Error: 40 : BindingExpression path error: 'AddCommand' property not found on 'object' ''String' 

Fix является в значительной степени получить DataContext через.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Style x:Key="LeftMenu" 
     TargetType="HeaderedContentControl"> 
    <Setter Property="HeaderTemplate"> 
     <Setter.Value> 
     <DataTemplate> 
      <StackPanel DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type HeaderedContentControl}}, Path=DataContext}"> 
      <Button Command="{Binding AddCommand}" 
        Content="Add" /> 
      </StackPanel> 
     </DataTemplate> 
     </Setter.Value> 
    </Setter> 
    <Setter Property="Width" 
      Value="160" /> 
    </Style> 
</ResourceDictionary> 

же вопрос относится и к ContentTemplate но Template работает отлично (Он использует ControlTemplate)

<Setter Property="Template"> 
    <Setter.Value> 
    <ControlTemplate TargetType="{x:Type HeaderedContentControl}"> 
     <StackPanel> 
     <Button Command="{Binding AddCommand}" 
       Content="Add" /> 
     </StackPanel> 
    </ControlTemplate> 
    </Setter.Value> 
</Setter> 
+1

Это решает проблему, но, безусловно, должно быть более элегантный подход, чем то, что я сделал? Было бы лучше объявить DataContext в словаре ресурсов вместо этого? Спасибо! – Dave

+4

@DaveRook Получение DataContext через привязку RelativeSource неплохо, когда вы знаете, что делаете. Однако, если вы попросите мое личное мнение, я бы тоже этого не сделал. Концепция ресурсного словаря - это повторное использование элементов управления, но когда у нас есть привязка к ресурсному словарю, вы в основном привязали «стиль» до очень специфического VM и View, что означает, что вам, возможно, было бы лучше определить его в самом элементе непосредственно. – Viv

+0

Wow, Viv, спасибо. Пиво на меня для этого. Да, я понимаю, почему вы придерживаетесь такого подхода, это поистине превосходная и огромная помощь. – Dave

Смежные вопросы