Я создал пользовательский 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
.
Любые идеи или предложения о том, как я могу продолжить с этим?
Заранее спасибо!
Я уже пробовал, но пишет, что не может получить доступ к GetValue
или SetValue
, нужно ли мне наследовать от какого-либо специального объекта?
Ваше свойство зависимостей VisibilityListener должно получить и установить логическое значение, а не двойное.
Вам нужно время как свойство или это действительно заданное значение, например 5 секунд или что-то в этом роде?
:facepalm: хороший момент @mm8, который решает часть, которая не работала в отношении Visibility
, но я все еще не могу создать DP для установки свойства ShowTime
Не совсем @andy, но я хотел бы научиться, я могу установить значение по умолчанию 3 или 5 секунд, и работа будет выполнена, но я ничему не научусь =D
Я думал, что вы могли бы использовать элемент фреймворка конвертера и привязать видимость. Вы можете поместить свойство в то, что может быть установлено, но не привязано.
Как насчет Behavior
в этом случае?
@Nekeniehl: Просто скопируйте первый и измените тип на int
? Кстати, смотрите мой ответ о поведении Blend.
Ваше свойство зависимостей 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>
Как вы думаете, как перейти на MVVM? Я считаю поведение не так ли?
@Nekeniehl: как присоединенное поведение, так и смешанное поведение подходят для MVVM. Какой подход использовать, зависит от ваших требований. Поведения смешивания нельзя использовать, например, в установщиках стилей, но они обеспечивают лучшую инкапсуляцию.
Определите другое присоединенное свойство для ShowTime.