C# 绑定到ViewModel中属性的DataTrigger未在DataGrid的按钮中激发

C# 绑定到ViewModel中属性的DataTrigger未在DataGrid的按钮中激发,c#,wpf,mvvm,controltemplate,datatrigger,C#,Wpf,Mvvm,Controltemplate,Datatrigger,我已经创建了ControlTemplates: <Window.Resources> <ControlTemplate x:Key="imgNo" TargetType="{x:Type Control}"> <Image Source="pack://application:,,,/Images/up.png"/> </ControlTemplate> <ControlTemplate x:Key=

我已经创建了
ControlTemplates

<Window.Resources>
    <ControlTemplate x:Key="imgNo" TargetType="{x:Type Control}">
        <Image Source="pack://application:,,,/Images/up.png"/>
    </ControlTemplate>

    <ControlTemplate x:Key="imgUp" TargetType="{x:Type Control}">
        <!--<TextBlock  Text="Up"/>-->
        <Image Source="pack://application:,,,/Images/up.png"/>
    </ControlTemplate>

    <ControlTemplate x:Key="imgDown" TargetType="{x:Type Control}">
        <Image Source="pack://application:,,,/Images/downArrow.png"/>
    </ControlTemplate>

    <DataTemplate x:Key="ButtonOneDataTemplate">
        <Control x:Name="theControl" Template="{DynamicResource imgNo}" />
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding IsImageChanged}" Value="true">
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgUp}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding IsImageChanged}" Value="false">
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgDown}" />
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</WindowResources>
<DataGrid ItemsSource="{Binding Persons}" Grid.Row="1" AutoGenerateColumns="False">
   <DataGrid.Columns>
     <DataGridTextColumn Binding="{Binding IdPerson}">
       <DataGridTextColumn.HeaderTemplate>                        
          <DataTemplate>
            <Border Background="Violet">
             <StackPanel>
                 <Button ContentTemplate="{StaticResource ButtonOneDataTemplate}" 
                 Command="{Binding DataContext.HelloCommand, RelativeSource=
                  {RelativeSource AncestorType=Window}}"
                  CommandParameter="{Binding DataContext.Hello,   
                RelativeSource={RelativeSource AncestorType=DataGrid}}"/> 
             </StackPanel>
            </Border>
         </DataTemplate>
       </DataGridTextColumn.HeaderTemplate>                   
     </DataGridTextColumn>
   </DataGrid.Columns>
 </DataGrid>                    
我的
视图模型

public class MainWindowViewModel:ViewModelBase
{
    public RelayCommand HelloCommand { get; set; }
    public MainWindowViewModel()
    {
       LoadPersons();
       HelloCommand = new RelayCommand(SayHello);
    }

    int helloCounter = 0;
    private void SayHello(object obj)
    {
       if (helloCounter % 2 == 0)
          IsImageChanged = true;
       else
          IsImageChanged = false;           
       helloCounter++;
    }


    private bool isImageChanged=true;
    public bool IsImageChanged
    {
       get { return isImageChanged; }
       set { isImageChanged = value;
             OnPropertyChanged("IsImageChanged");
           }
    }
}
我想要的是当我点击按钮
,然后
模板
应该被替换为
{DynamicResource imgDown}
{DynamicResource imgUp}
<代码>数据触发器取决于
IsImageChanged


但是,如果我单击
按钮
,则不会触发
数据触发器
控制模板
,例如
imgUp
imgDown
)。如何从ViewModel中实现这一点?

问题在于DataGrid列不是可视化树的一部分,因此它不会继承DataContext。为了能够在ButtonOneDataTemplate中使用DataTriggers,您需要应用此模板的按钮具有正确的DataContext。下面介绍了一个技巧,即如何为VisualTree中不存在的元素提供DataContext

将该解决方案应用到您的代码中,我们将得到以下结果:

代理

窗口资源

    <local:BindingProxy x:Key="proxy" Data="{Binding}" />

    <DataTemplate x:Key="ButtonOneDataTemplate">
        <Control x:Name="theControl" Template="{DynamicResource imgNo}" Foreground="Orange"/>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.IsImageChanged}" Value="True">
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgUp}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.IsImageChanged}" Value="False">
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgDown}" />
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>

头模板

<DataGridTextColumn.HeaderTemplate>
    <DataTemplate>
        <Border Background="Violet">
            <StackPanel>
                <Button ContentTemplate="{StaticResource ButtonOneDataTemplate}" 
                        DataContext="{Binding Path=Data, Source={StaticResource proxy}}"
                        Command="{Binding DataContext.ButtonClick, RelativeSource={RelativeSource AncestorType=Window}}"
                        CommandParameter="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
            </StackPanel>
        </Border>
    </DataTemplate>
</DataGridTextColumn.HeaderTemplate>


问题在于DataGrid列不是可视树的一部分,因此它不继承DataContext。为了能够在ButtonOneDataTemplate中使用DataTriggers,您需要应用此模板的按钮具有正确的DataContext。下面介绍了一个技巧,即如何为VisualTree中不存在的元素提供DataContext

将该解决方案应用到您的代码中,我们将得到以下结果:

代理

窗口资源

    <local:BindingProxy x:Key="proxy" Data="{Binding}" />

    <DataTemplate x:Key="ButtonOneDataTemplate">
        <Control x:Name="theControl" Template="{DynamicResource imgNo}" Foreground="Orange"/>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.IsImageChanged}" Value="True">
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgUp}" />
            </DataTrigger>
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext.IsImageChanged}" Value="False">
                <Setter TargetName="theControl" Property="Template" Value="{DynamicResource imgDown}" />
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>

头模板

<DataGridTextColumn.HeaderTemplate>
    <DataTemplate>
        <Border Background="Violet">
            <StackPanel>
                <Button ContentTemplate="{StaticResource ButtonOneDataTemplate}" 
                        DataContext="{Binding Path=Data, Source={StaticResource proxy}}"
                        Command="{Binding DataContext.ButtonClick, RelativeSource={RelativeSource AncestorType=Window}}"
                        CommandParameter="{Binding DataContext, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
            </StackPanel>
        </Border>
    </DataTemplate>
</DataGridTextColumn.HeaderTemplate>


请提供全视图模型代码。你仍然不清楚目标。您想通过此实现什么?@Gopichandar请查看我的升级问题。请提供完整的viewmodel代码。你仍然不清楚目标。“你想用这个达到什么目的?@Gopichandar请看我的升级问题,谢谢,伙计!”!这真的很有效!:)非常感谢你!万分感谢,老兄!这真的很有效!:)非常感谢你!