#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. Какой подход использовать, зависит от ваших требований. Например, поведение смешивания нельзя использовать в установщиках стилей, но они обеспечивают лучшую инкапсуляцию.