如何有条件地隐藏部分WPF控件?

时间:2013-01-24 18:37:16

标签: c# wpf mvvm controls behavior

我在程序集中有一个控件,我无法更改,这与.NET DateTimePicker非常相似。我想在满足某个条件时隐藏该控件的时间选择器部分(我的ViewModel上的属性值)。控件如下所示:

[TemplatePart(Name = "PART_DatePicker", Type = typeof (DatePicker))]
[TemplatePart(Name = "PART_TimePicker", Type = typeof (TimePicker))]
public class MyDateTimePicker : Control    {/*...*/}

这个答案显示了一种总是隐藏控件PART的好方法,但我想动态地执行它:

How to hide a part of a WPF control

我想有几种方法可以做到这一点。我想要的是最小的东西(比如链接问题的答案)以及不违反MVVM的东西。 System.Interactivity行为和触发器是公平的游戏。

3 个答案:

答案 0 :(得分:3)

创建一个扩展前一个控件的新控件

public sealed class MySuperiorDateTimePicker : MyDateTimePicker 
{
    //....

添加可以绑定到ViewModel状态的DependencyProperty

public static readonly DependencyProperty HideItProperty =
    DependencyProperty.Register(
        "HideIt",
        typeof(bool),
        typeof(MySuperiorDateTimePicker ),
        new UIPropertyMetadata(false, HideItPropertyChanged));
//snip property impl

等待属性更改,然后隐藏您的UI

private static void HideItPropertyChanged(DependencyObject d,
    DependencyPropertyChangedEventArgs e)
{
    (d as MySuperiorDateTimePicker).OnHideItChanged((bool)e.OldValue, 
        (bool)e.NewValue);
}

private void OnHideItChanged(bool oldValue, bool newValue)
{
    if(BusyTemplate == null)
        return;
    FindTimePicker().Visibility = newValue ? Visibility.Visible : 
        Visibility.Collapsed;
}

private UIElement FindTimePicker()
{
    //snip null checks
    return GetTemplateChild("PART_TimePicker") as UIElement;
}

小心FindTimePicker,因为在加载控件之前DP可能会更改,GetTemplateChild将返回null。通常要做的是,在OnHideItChanged中,如果GetTemplateChild返回 null ,请稍后使用Dispatcher.BeginInvoke重新运行事件处理程序(ApplicationIdle或更早)。

当您发现自己说“我如何使用MVVM进行UI工作”时,请停下来并重新考虑您的真实目标。 MVVM!=没有代码隐藏,没有自定义控件等等。

答案 1 :(得分:0)

一种解决方案是在datatemplate中定义的DataTrigger的帮助下隐藏它,这样当控件的datacontext中的某个值设置为true / false时,您将隐藏/显示该部分。

快速搜索,我找到了一些您可能会觉得有用的链接: http://zamjad.wordpress.com/2010/06/22/conditionally-hide-controls-from-data-template/ http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/ae2dbfb7-5dd6-4352-bfa1-53634289329d/

答案 2 :(得分:0)

对我有用的解决方案是编辑控件的样式。使用Blend,我编辑了DateTimePicker样式的副本,并添加了一个绑定到TimePicker的Visibility,它可以查看我的VM并转换枚举的值。