1

ですから、私はWPFを初めて使用するので、これは些細なことかもしれませんが、理解できません。

テキストボックスがあります。

<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

1 に答える 1

4

スタイルを介してビヘイビアプロパティを変更することはできませんが、スタイルを介してビヘイビアを適用することはできます。このような他の質問では主題が省略されていますが、特定のケースでは、スタイルを介して動作を適用するだけでなく、データに応じて異なる構成で適用する必要があります。次のアプローチでは、添付プロパティを使用してそれを実現します。まず、使用しているものと同様のダミーの動作:

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のDataContextの状態に応じて、異なるDecimalLimitを適用するTextBoxスタイルがあります。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>

コードビハインドでは、ボタンのアクションでTextBoxの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のテキストが変更されます。これは、スタイルが実際に正しい動作を適用していることを意味します。

于 2012-11-16T15:56:41.450 に答える