Can not bind within resource dictionary

2019-03-27 19:30发布

I'm running a simple MVVM project and fallen at the first hurdle. I'm binding my commands using Josh Smiths Relay Command approach.

The problem is, the button isn't binding when the button is in the ResourceDictionary. If I move the code (exactly as is) into my MainWindow.xaml then the code executes as desired.

This is my 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>

And the resource dictionary

<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>

I can only assume that when binding in the ResourceDictionary that it can't find the ViewModel (although I don't know why I think that). I think it's trying to bind an extra level down...

Any way, can some one explain why it's not executing from within the Resource Dictionary please.

标签: c# wpf mvvm
1条回答
不美不萌又怎样
2楼-- · 2019-03-27 20:08

This issue seems to have not much to do with the ResourceDictionary than having the parent DataContext pass to the DataTemplate

If you copy the Style and put it into the Grid.Resources and comment the resource dictionary the same behavior can be seen. Also turning on Binding errors should show

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

Fix is pretty much get the DataContext through.

<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>

same issue applies to ContentTemplate but Template works fine(It uses a ControlTemplate)

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type HeaderedContentControl}">
      <StackPanel>
        <Button Command="{Binding AddCommand}"
                Content="Add" />
      </StackPanel>
    </ControlTemplate>
  </Setter.Value>
</Setter>
查看更多
登录 后发表回答