2016-12-04 8 views
0

添付プロパティを使用するとトリガーが更新されません。まずWPF:DataTriggerを手動で更新する方法

Window1.xaml

<Window x:Class="proj1.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:proj1" 
     mc:Ignorable="d" 
     Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 
     <Style TargetType="ListView" x:Key="style1"> 
      <Setter Property="View"> 
       <Setter.Value> 
        <GridView> 
         <GridViewColumn Header="1" DisplayMemberBinding="{Binding one}" Width="100" /> 
         <GridViewColumn Header="2" DisplayMemberBinding="{Binding two}" Width="100" /> 
        </GridView> 
       </Setter.Value> 
      </Setter> 
      <EventSetter Event="GridViewColumnHeader.Click" Handler="ColumnHeader_Click"/> 
      <Style.Triggers> 
       <!-- 
       <Trigger Property="Column.local:TestClass.Flag" Value="True"> 
        <Setter Property="Foreground" Value="Red" /> 
       </Trigger> 
       --> 
      </Style.Triggers> 
     </Style> 
     <Style TargetType="ListView" x:Key="style2"> 
      <Setter Property="View"> 
       <Setter.Value> 
        <GridView> 
         <GridViewColumn Header="1" DisplayMemberBinding="{Binding one}" Width="100" /> 
         <GridViewColumn Header="2" DisplayMemberBinding="{Binding two}" Width="100" /> 
        </GridView> 
       </Setter.Value> 
      </Setter> 
      <EventSetter Event="GridViewColumnHeader.Click" Handler="ColumnHeader_Click"/> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Column, RelativeSource={RelativeSource Self}, Converter={x:Static local:TestClass.Converter}}" Value="True"> 
        <Setter Property="Foreground" Value="Red" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 

     <ListView Grid.Row="0" Style="{StaticResource style1}" ItemsSource="{Binding items}" /> 
     <ListView Grid.Row="1" Style="{StaticResource style2}" ItemsSource="{Binding items}" /> 

    </Grid> 
</Window> 

Window1.xaml.cs

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Shapes; 

namespace proj1 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      // set dummy data 
      this.DataContext = new 
      { 
       items = new[] 
       { 
        new { 
         one = "A", 
         two = "a", 
        }, 
        new { 
         one = "B", 
         two = "b", 
        }, 
        new { 
         one = "C", 
         two = "c", 
        }, 
        new { 
         one = "D", 
         two = "d", 
        }, 
       } 
      }; 
     } 

     /// <summary> 
     /// cannot change! 
     /// </summary> 
     /// <param name="sender"></param> 
     /// <param name="e"></param> 
     private void ColumnHeader_Click(object sender, RoutedEventArgs e) 
     { 
      var column_header = e.OriginalSource as GridViewColumnHeader; 

      if (column_header == null) return; 

      var column = column_header.Column; 

      if (column == null) return; 

      TestClass.Setflag(column, !TestClass.GetFlag(column)); 

      // debug print 
      Console.WriteLine($"{column_header.Content}/{TestClass.GetFlag(column)}"); 
     } 
    } 

    /// <summary> 
    /// Define 'Flag' AttachedProprety and IValueCoverter which pick 
    /// 'Flag' AttachedProperty from a DependencyObject 
    /// </summary> 
    public class TestClass 
    { 
     public static bool GetFlag(DependencyObject obj) 
     { 
      return (bool)obj.GetValue(FlagProperty); 
     } 

     public static void Setflag(DependencyObject obj, bool value) 
     { 
      obj.SetValue(FlagProperty, value); 
     } 

     // Using a DependencyProperty as the backing store for flag. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty FlagProperty = 
      DependencyProperty.RegisterAttached("Flag", typeof(bool), typeof(TestClass), new PropertyMetadata(false)); 

     public static IValueConverter Converter => new GetFlagConverter(); 

     public class GetFlagConverter : IValueConverter 
     { 
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
      { 
       var dobj = value as DependencyObject; 
       if (dobj == null) 
       { 
        return false; 
       } 

       return GetFlag(dobj); 
      } 

      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
      { 
       throw new NotImplementedException(); 
      } 
     } 
    } 
} 

、私は "STYLE1" のコードを試してみました。しかし、 "Column.local:TestClass.Flag"にはエラーがあります。

私は "style2"コードを試しました。エラーはありません。

ただし、フォントの色は変更されませんでした。

DataTriggerを手動で更新するにはどうすればよいですか?

+1

同じシナリオをシミュレートするために、可能な限り少ないコードを投稿してください。それはあなたに速い答えを与え、また読みやすくなります。 – MYGz

答えて

0

トリガーターゲットとトリガーを設定したオブジェクト(スタイル1)の間に問題があります。ヘッダーテキストを色付けするには、次のように変更する必要があります。

<Style x:Key="style1" TargetType="ListView"> 
    <Setter Property="View"> 
     <Setter.Value> 
      <GridView> 
       <GridViewColumn Width="100" 
           DisplayMemberBinding="{Binding one}" 
           Header="1"> 
        <GridViewColumn.HeaderContainerStyle> 
         <Style TargetType="GridViewColumnHeader"> 
          <Style.Triggers> 
           <Trigger Property="local:TestClass.Flag" Value="True"> 
            <Setter Property="Foreground" Value="Red" /> 
           </Trigger> 
          </Style.Triggers> 
         </Style> 
        </GridViewColumn.HeaderContainerStyle> 
       </GridViewColumn> 
       <GridViewColumn Width="100" 
           DisplayMemberBinding="{Binding two}" 
           Header="2" > 
        <GridViewColumn.HeaderContainerStyle> 
         <Style TargetType="GridViewColumnHeader"> 
          <Style.Triggers> 
           <Trigger Property="local:TestClass.Flag" Value="True"> 
            <Setter Property="Foreground" Value="Red" /> 
           </Trigger> 
          </Style.Triggers> 
         </Style> 
        </GridViewColumn.HeaderContainerStyle> 
       </GridViewColumn> 
      </GridView> 
     </Setter.Value> 
    </Setter> 
    <EventSetter Event="GridViewColumnHeader.Click" Handler="ColumnHeader_Click" /> 
</Style> 

private void ColumnHeader_Click(object sender, RoutedEventArgs e) 
{ 
    var column_header = e.OriginalSource as GridViewColumnHeader; 

    if (column_header == null) return; 

    TestClass.Setflag(column_header, !TestClass.GetFlag(column_header)); 
} 

これはあなたのColumnHeader要素のFlagを設定します。現在、Style.TriggerColumnHeaderにあり、正しく実行されています。

+0

'flag'は別の理由で' column'に設定しなければなりません。 その場合、 'column'と' header'の両方を設定する必要がありますか? できれば 'column'に対して' flag'だけを設定したいと思います。 – blz

関連する問題