2012-11-16 22 views
1

所以,我是WPF的新手,所以也许这是微不足道的,但我无法弄清楚。XAML样式,在DataTrigger上设置行为属性

我有一个文本框。

<TextBox Text="{Binding NewRateAdjustment.Amount, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True,ValidatesOnExceptions=True}" Style="{StaticResource SurchargeAmountTextBox}" AttachedProperties:TextRules.TextRule ="{StaticResource numericRule}"> 
    <i:Interaction.Behaviors> 
     <gl:NumericTextBoxBehavior DecimalLimit="2" /> 
    </i:Interaction.Behaviors> 
</TextBox> 

现在,我需要根据页面下拉选项更改DecimalLimit,所以我创建了这个样式。

<Style x:Key="SurchargeAmountTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource DefaultTextBox}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Path=NewRateAdjustment.SelectedRateAdjustment.CalculationMethod.Name, UpdateSourceTrigger=PropertyChanged}" Value="Fuel"> 
      <Setter Property="Background" Value="Red"/> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding Path=NewRateAdjustment.SelectedRateAdjustment.CalculationMethod.Name, UpdateSourceTrigger=PropertyChanged}" Value=""> 
      <Setter Property="Background" Value="Green"/> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

它似乎适用于颜色。但是,如何编写DecimalLimit的属性设置器?

回答

4

您不能通过样式更改行为属性,但您可以尝试通过样式尝试应用的行为。这个问题已经在其他问题上得到了解决,如this,但在您的特定情况下,您不仅要通过样式应用行为,还要根据数据将其应用于不同的配置。 在以下方法中,我将使用附加属性来完成该操作。 首先,虚拟的行为类似于你正在使用的一个:

public class NumericTextBoxBehavior : Behavior<TextBox> 
{ 
    public double DecimalLimit { get; set; } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     // Dummy action so we can see the change when its applied 
     this.AssociatedObject.Text = this.DecimalLimit.ToString(); 
    } 
} 

现在,我们创建了一个附加属性是去是负责应用的行为(你可以做到这一点的另一个类,或者在行为类如果您有权访问它):

public static class NumericTextBoxBehaviorExtension 
{ 
    public static double? GetDecimalLimit(DependencyObject obj) 
    { 
     return (double?)obj.GetValue(DecimalLimitProperty); 
    } 
    public static void SetDecimalLimit(DependencyObject obj, double? value) 
    { 
     obj.SetValue(DecimalLimitProperty, value); 
    } 
    public static readonly DependencyProperty DecimalLimitProperty = 
     DependencyProperty.RegisterAttached("DecimalLimit", typeof(double?), typeof(NumericTextBoxBehaviorExtension), new PropertyMetadata(null, OnDecimalLimitChanged)); 

    private static void OnDecimalLimitChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) 
    { 
     var behaviors = Interaction.GetBehaviors(sender); 

     // Remove the existing behavior instances 
     foreach (var old in behaviors.OfType<NumericTextBoxBehavior>().ToArray()) 
      behaviors.Remove(old); 

     if (args.NewValue != null) 
     { 
      // Creates a new behavior and attaches to the target 
      var behavior = new NumericTextBoxBehavior { DecimalLimit = (double)args.NewValue }; 

      // Apply the behavior 
      behaviors.Add(behavior); 
     } 
    } 
} 

最后,下面的测试用例将模拟您的场景。我们有一个TextBox样式,它将根据TextBox的DataContext的状态应用不同的DecimalLimit。 XAML中:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <Style x:Key="TextBoxStyle" TargetType="TextBox"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding Name}" Value="Fuel"> 
       <Setter Property="local:NumericTextBoxBehaviorExtension.DecimalLimit" Value="10.0"/> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding Name}" Value=""> 
       <Setter Property="local:NumericTextBoxBehaviorExtension.DecimalLimit" Value="1000.0"/> 
      </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<Grid> 
    <Button Content="Button" Height="23" HorizontalAlignment="Left" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" /> 
    <TextBox Height="23" HorizontalAlignment="Left" Margin="81,1,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" Style="{StaticResource TextBoxStyle}"/> 
</Grid> 

在后面的代码,我们将按钮的动作互换文本框的DataContext的验证风格将更新正确的行为:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     var target = this.textBox1.DataContext as Target; 
     if (this.textBox1.DataContext == null || string.IsNullOrEmpty(target.Name)) 
     { 
      this.textBox1.DataContext = new Target() { Name = "Fuel" }; 
     } 
     else 
     { 
      this.textBox1.DataContext = new Target() { Name = "" }; 
     } 
    } 
} 

,你可以看到,每次我们交换DataContext时,TextBox的Text都会改变,这意味着这种风格确实是正确的行为。

+0

这不是一个DependencyProperty。我已经尝试只是将属性添加到ViewModel并绑定到该模型。它失败了。 – CaffGeek

+0

让我们尝试使用附加属性,然后!见编辑的答案。 –

+0

仍然不起作用,它似乎一旦设置,它是最终的。 – CaffGeek