在风格中使用行为

时间:2017-06-08 10:20:16

标签: c# wpf attachedbehaviors

我有一个行为,如何在TextBlock Style中使用它,以便它应用于所有TextBlocks。

<TextBlock Grid.Row="0"  Grid.Column="1" Text="{Binding Distance}" >
        <i:Interaction.Behaviors>
            <Behaviors:EmptyToNaBehaviour/>
        </i:Interaction.Behaviors>
</TextBlock>

这是我的附加行为,它基本上将空值更改为N / A

 public class EmptyToNaBehaviour : Behavior<TextBlock>
{
    protected override void OnAttached()
    {
        var txtblock = this.AssociatedObject as TextBlock;

        if (txtblock != null && string.IsNullOrEmpty(txtblock.Text))
        {
            txtblock.Text = "N/A";
        }
    }
}

1 个答案:

答案 0 :(得分:1)

在WPF中实现行为基本上有两种不同的方式,通常称为附加行为和混合行为。

附加行为只是一个附加属性,附加了PropertyChangedCallback更改处理程序,当依赖项属性的值更改时,它会对其附加的DependencyObject执行某些操作或扩展它。

通常将附加行为定义为具有一组静态方法的静态类,这些静态方法获取并设置依赖项属性的值,并在调用回调时执行所需的逻辑。您可以在样式中轻松设置任何此类属性的值:

<Setter Property="local:EmptyToNaBehaviour.SomeProperty" Value="x"/>

与普通附加行为相比,混合行为提供了封装行为功能的更好方法。它们也更容易设计,因为它们可以通过Blend中的拖放功能轻松附加到UI中的可视元素。但是我担心你无法在Style setter中添加Blend行为:

How to add a Blend Behavior in a Style Setter

因此,如果您希望能够在Style的上下文中应用您的行为,则应该编写附加行为而不是混合行为。

编辑:您的行为是混合行为。将其替换为附加行为:

public class EmptyToNaBehaviour
{
    public static string GetText(TextBlock textBlock)
    {
        return (string)textBlock.GetValue(IsBroughtIntoViewWhenSelectedProperty);
    }

    public static void SetText(TextBlock textBlock, string value)
    {
        textBlock.SetValue(IsBroughtIntoViewWhenSelectedProperty, value);
    }

    public static readonly DependencyProperty IsBroughtIntoViewWhenSelectedProperty =
        DependencyProperty.RegisterAttached(
        "Text",
        typeof(string),
        typeof(EmptyToNaBehaviour),
        new UIPropertyMetadata(null, OnTextChanged));

    private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBlock txtblock = d as TextBlock;
        if(txtblock != null)
            txtblock.Loaded += Txtblock_Loaded;
    }

    private static void Txtblock_Loaded(object sender, RoutedEventArgs e)
    {
        TextBlock txtblock = sender as TextBlock;
        string text = GetText(txtblock);
        if (txtblock != null && !string.IsNullOrEmpty(text) && string.IsNullOrEmpty(txtblock.Text))
        {
            txtblock.Text = text;
        }
    }
}

<强>用法:

<TextBlock Grid.Row="0"  Grid.Column="1" Text="text"
           Behaviors:EmptyToNaBehaviour.Text="N/A">
</TextBlock>

或风格:

<Style x:Key="style" TargetType="TextBlock">
    <Setter Property="Behaviors:EmptyToNaBehaviour.Text" Value="N/A" />
</Style>