Поведение при снятии / скрытии элемента фреймворка

#c# #wpf #xaml

#c# #wpf #xaml

Вопрос:

Я создал пользовательский TextBlock интерфейс, который изменяет значение Visibility через несколько секунд, указанное DependencyProperty ShowTime :

 <customUserControl:AutoHideTextBlock Text="AutoHideTextBlock" Visibility="{Binding IsVisibleEnabled, Converter={StaticResource BoolToVisConverter}}" ShowTime="3"/>
  

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

 public class AutoHideExtension
{
    public static readonly DependencyProperty VisibilityListenerProperty =
        DependencyProperty.RegisterAttached(
            "VisibilityListener",
            typeof(bool),
            typeof(AutoHideExtension),
            new PropertyMetadata(false, VisibilityChanged));

    public static double GetVisibilityListener(DependencyObject obj)
        => (double)obj.GetValue(VisibilityListenerProperty);

    public static void SetVisibilityListener(DependencyObject obj, double value)
        => obj.SetValue(VisibilityListenerProperty, value);

    private static void VisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var element = (FrameworkElement)d;

        if (element.Visibility == Visibility.Collapsed || !IsLoaded)
            {
                return;
            }

        DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Background)
                                    {
                                        Interval =
                                            new TimeSpan(
                                            0,
                                            0,
                                            ShowTime)
                                    };

        timer.Tick  = (senderEvent, args) =>
            {
                element.Visibility = Visibility.Collapsed;
                timer.Stop();
            };

        timer.Start();
    }
}
  

Идея заключается в том, что я могу прикрепить это новое свойство к любому элементу и изменить видимость по истечении указанного времени, примерно следующим образом:

 <TextBlock Text="TextToHide"
            helpers:AutoHideExtension.VisibilityListener="{Binding ChangesSavedEnabled}"/>
  

Проблема в том, что я не знаю, как указать свойство ShowTime as в классе расширения, и что это просто не работает, поскольку не изменяет Visibility .

Любые идеи или предложения о том, как я могу продолжить работу с этим?

Заранее спасибо!

Комментарии:

1. Определите другое присоединенное свойство для времени показа.

2. Я уже пробовал, но он говорит, что не может получить доступ к GetValue или SetValue , должен ли я наследовать от какого-либо специального объекта?

3. Ваше свойство зависимости VisibilityListener должно получать и устанавливать значение bool, а не double .

4. Вам нужно время как свойство или это действительно установленное значение, например, 5 секунд или что-то в этом роде?

5. :facepalm: хорошая точка @ mm8, которая решает ту часть, которая не работала в отношении Visibility , но я все еще не могу создать DP для установки свойства ShowTime

Ответ №1:

Ваше свойство dependency VisibilityListener должно получить и установить bool значение:

 public static bool GetVisibilityListener(DependencyObject obj)
    => (bool)obj.GetValue(VisibilityListenerProperty);

public static void SetVisibilityListener(DependencyObject obj, bool value)
    => obj.SetValue(VisibilityListenerProperty, value);
  

Затем вы могли бы определить другое присоединенное свойство для ShowTime, или вы могли бы определить поведение смешивания, которое содержит два свойства:

 <TextBlock xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
          Text="TextToHide">
    <i:Interaction.Behaviors>
        <local:AutoHideExtensionBehavior VisibilityListener="{Binding ChangesSavedEnabled}" ShowTime="3" />
    </i:Interaction.Behaviors>
</TextBlock>
  

Комментарии:

1. Как вы думаете, как поступить с MVVM? Я считаю, что поведение правильное?

2. @Nekeniehl: прикрепленное поведение и смешанное поведение вписываются в MVVM. Какой подход использовать, зависит от ваших требований. Например, поведение смешивания нельзя использовать в установщиках стилей, но они обеспечивают лучшую инкапсуляцию.