2016-03-08 2 views
1

Я пытаюсь изменить цвет формы с помощью привязки данных и триггера данных.WPF Databinding DataTrigger для изменения цвета формы на основе логического значения

Но я все еще новичок в WPF и все.

Позвольте мне проиллюстрировать пример. это коробка группа

<GroupBox x:Class="Server.Host.SingleAxisControls" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:host="clr-namespace:Server.Host" 
     mc:Ignorable="d" 
     d:DesignWidth="200"> 
    <Grid> 
     <StackPanel Orientation="Vertical" Width="180" > 
      <host:MyRectangleControl x:Name="MyRectangle" /> 
      <Button Click="OnButton_Click" Width="80" Margin="20,5,20,5">On</Button> 
      <Button Click="OffButton_Click" Width="80">Off</Button> 
     </StackPanel> 
    </Grid> 
</GroupBox> 

MyRectangleControl является UserControl что-то вроде

<UserControl x:Class="Server.Host.MyRectangleControl" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="30" d:DesignWidth="30"> 
<Grid> 
    <Rectangle HorizontalAlignment="Center" 
       Height="25" 
       Margin="0,0,0,0" 
       Stroke="Black" 
       VerticalAlignment="Center" 
       Width="25" 
       Fill="red"> 
     <Rectangle.Style> 
      <Style TargetType="Rectangle"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding Path=Test,UpdateSourceTrigger=PropertyChanged}" 
           Value="True"> 
         <Setter Property="Fill" 
           Value="Green" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </Rectangle.Style> 
    </Rectangle> 
</Grid> 

В коде позади GroupBox, у меня есть что-то вроде

namespace Server.Host 
{ 
public partial class SingleAxisControls : INotifyPropertyChanged 
{ 
    public SingleAxisControls() 
    { 
     InitializeComponent(); 

     MyRectangle.DataContext = this; 
    } 

    private bool _test; 
    public bool Test 
    { 
     get { return _test; } 
     set 
     { 
      _test = value; 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("Test")); 
      } 
     } 
    } 

    private void OnButton_Click(object sender, RoutedEventArgs e) 
    { 
     Test = true; 
    } 

    private void OffButton_Click(object sender, RoutedEventArgs e) 
    { 
     Test = false; 
    } 
} 

Я не уверен, что не так, но он не изменит цвет прямоугольника, когда я меняю значение теста от ложного до истинного.

Любой совет будет очень благодарен.

ответ

5

Это проблема value precedence.

Когда вы устанавливаете DependencyProperty непосредственно в объявлении элемента, это значение имеет более высокий приоритет, чем значение, заданное в стиле.

Все, что вам нужно сделать, это установить свойство Fill на красный в стиле:

<Rectangle HorizontalAlignment="Center" 
      Height="25" 
      Margin="0,0,0,0" 
      Stroke="Black" 
      VerticalAlignment="Center" 
      Width="25" 
      > 
    <Rectangle.Style> 
     <Style TargetType="Rectangle"> 
      <Setter Property="Fill" Value="Red"/> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Path=Test,UpdateSourceTrigger=PropertyChanged}" 
          Value="True"> 
        <Setter Property="Fill" 
          Value="Green" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Rectangle.Style> 
</Rectangle> 
+0

Вы являетесь чемпионом. Спасибо, что указали мне. – CJC

0

Другим допустимым вариантом является написание преобразователя к связыванию. Это будет выглядеть следующим образом:

class BooleanToBrushConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, System.Globalization.CultureInfo culture) 
     { 
      if ((bool)value) 
      { 
       return new SolidColorBrush(Colors.Black); 
      } 
      return new SolidColorBrush(Colors.LightGray); 
     } 

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

(Вы можете установить цвета на все, что вы хотите) и Xaml будет выглядеть следующим образом:

<Rectangle HorizontalAlignment="Center" 
       Height="25" 
       Margin="0,0,0,0" 
       Stroke="Black" 
       VerticalAlignment="Center" 
       Width="25" 
       Fill="{Binding Test, Converter={StaticResource b2b}}"> 

с этим в верхней части XAML:

<UserControl.Resources> 
    <BooleanToBrushConverter x:Key="b2b" /> 
</UserControl.Resources> 

Примечание: если ваш конвертер находится в другом месте, вам необходимо включить его в пространство имен и предисловие объявления с помощью того, что вы назвали пространством имен, то есть

xlmns:converters="clr-namespace:Project.Converters" 

в <UserControl> теге , а затем <converters: BooleanToBrushConverter x:Key="b2b" /> в ресурсах