Как установить Behavior через триггер

153
21 марта 2019, 12:30

Предположим, у меня есть некий контролл:

<TextBox Text="Hello world"
             Margin="5,7">
</TextBox>

Нужно поставить ему Behavior, если триггер сработает, то есть по факту написать так:

<TextBox Text="Hello world"
             Margin="5,7">
    <Style TargetType="{x:Type TextBox}">
       <Style.Triggers>
          <Trigger Property="IsVisible" Value="False">
             <i:Interaction.Behaviors>
                <behaviors:MyBehavior />
             </i:Interaction.Behaviors>
          </Trigger>
       </Style.Triggers>
     </Style>
</TextBox>

Как это можно сделать? И можно ли вообще?

Answer 1

Можно вывернуть проблему: привязать behavior сразу, подписаться на IsVisibleChanged в behavior, а дальше то зачем вам это нужно

class MyBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.IsVisibleChanged += AssociatedObject_IsVisibleChanged;
    }
    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.IsVisibleChanged -= AssociatedObject_IsVisibleChanged;
    }
    void AssociatedObject_IsVisibleChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
    {
        //TODO: сделать что-нибудь
    }        
}

xaml:

<TextBox Text="Hello world">    
    <i:Interaction.Behaviors>
        <behaviors:MyBehavior/>
    </i:Interaction.Behaviors>         
</TextBox>
Answer 2

Можно поступить следующим образом, добавьте в ваш класс поведения такое свойство зависимости:

public static bool GetInject(DependencyObject obj)
    => (bool)obj.GetValue(InjectProperty);
public static void SetInject(DependencyObject obj, bool value)
    => obj.SetValue(InjectProperty, value);
public static readonly DependencyProperty InjectProperty =
    DependencyProperty.RegisterAttached("Inject", typeof(bool),
        typeof(MyBehavior), new PropertyMetadata(false, OnInject));
static void OnInject(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    bool newValue = (bool)e.NewValue;
    var behaviours = Interaction.GetBehaviors(d);
    if (newValue)
    {
        behaviours.Add(new MyBehavior());
    }
    else
    {
        foreach (var b in behaviours.OfType<MyBehavior>().ToList())
            behaviours.Remove(b);
    }
}

Теперь, если установить Inject=true, это поведение применится автоматически. Сделайте это в вашем триггере:

<TextBox Text="Hello world" Margin="5,7">
    <Style TargetType="{x:Type TextBox}">
       <Style.Triggers>
          <Trigger Property="IsVisible" Value="False">
             <Setter Property="behaviors:MyBehavior.Inject" Value="True"/>
          </Trigger>
       </Style.Triggers>
     </Style>
</TextBox>

Взято из этого ответа @VladD.

READ ALSO
Общие вопросы по c# [закрыт]

Общие вопросы по c# [закрыт]

Можем ли мы в интерфейсах создавать, что то вроде поля классаНапример мне нужно чтобы в интерфейсе был: Mysqlconnection

161
C# WPF после обновления студии MVS, начал глючит DataGrid

C# WPF после обновления студии MVS, начал глючит DataGrid

Обновил студию Microsoft Visual Studio и DataGrid в WPF приложении стало абсолютно неадекватно себя вести:

185
C# ASP.NET Core Identity регистрация в DI UserManager, RoleManager без вызова AddIdentity

C# ASP.NET Core Identity регистрация в DI UserManager, RoleManager без вызова AddIdentity

Есть отдельный WebApi проект над базой данных пользователей "UserDbWebApi", которую использует проект для авторизации на IdentityServer4 "IdentityServerApi_AspNetIdentity"

154
Проверка прокручен ли скролл richTextBox до конца

Проверка прокручен ли скролл richTextBox до конца

Моя задача такова, когда пользователь прокрутит скролл до конца текста выполняется нужный мне кодНо сколько не искал, не смог найти способа...

155