无法在资源字典中绑定

Dav*_*ave 7 c# wpf mvvm

我正在运行一个简单的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>
Run Code Online (Sandbox Code Playgroud)

和资源字典

<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>
Run Code Online (Sandbox Code Playgroud)

我只能假设在ResourceDictionary中绑定它无法找到ViewModel(虽然我不知道为什么我认为).我认为它试图将额外的水平降低......

无论如何,有人可以解释为什么它不是从资源字典中执行的.

Viv*_*Viv 8

这个问题似乎与ResourceDictionary没有多大关系,而是将父DataContext传递给了DataTemplate

如果您复制Style并将其放入Grid.Resources并注释资源字典,则可以看到相同的行为.还应显示打开Binding错误

System.Windows.Data Error: 40 : BindingExpression path error: 'AddCommand' property not found on 'object' ''String'
Run Code Online (Sandbox Code Playgroud)

修复几乎是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>
Run Code Online (Sandbox Code Playgroud)

同样的问题适用ContentTemplateTemplate工作正常(它使用a ControlTemplate)

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type HeaderedContentControl}">
      <StackPanel>
        <Button Command="{Binding AddCommand}"
                Content="Add" />
      </StackPanel>
    </ControlTemplate>
  </Setter.Value>
</Setter>
Run Code Online (Sandbox Code Playgroud)

  • @DaveRook当你知道你在做什么时,通过RelativeSource绑定获取DataContext并不坏.但是,如果你要求我的个人意见,我也不会这样做.资源字典的概念是我们重用控件的,但是当我们在资源字典中有绑定时,你基本上将`Style`绑定到一个非常特定的VM和View,这意味着你可能最好在Item本身中定义它直. (4认同)