zoukankan      html  css  js  c++  java
  • WPF实战案例-MVVM模式下用附加属性在Xaml中弹出窗体

    嗯。。最近回家去了,2个月没写过代码了,面试只能吹牛,基础都忘了,今天回顾一下,分享一篇通过附加属性去处理窗体弹出的情况。

    或许老司机已经想到了,通过设置附加属性值,值变更的回调函数去处理窗体弹出,是的,很简单,想法的问题。

    public static readonly DependencyProperty IsModalProperty =
                        DependencyProperty.RegisterAttached("IsModal", typeof(bool), typeof(WindowHelper), new PropertyMetadata(true));
    
            public static readonly DependencyProperty OpenWindowTypeProperty =
                                DependencyProperty.RegisterAttached("OpenWindowType", typeof(Type), typeof(WindowHelper), new PropertyMetadata(null, OnOpenWindowTypeChanged));
    
            public static readonly DependencyProperty ParameterProperty =
                DependencyProperty.RegisterAttached("Parameter", typeof(object), typeof(WindowHelper), new PropertyMetadata(null));

    三个附加属性,是否模态窗口,窗口类型,传递到窗口的参数,事实上其实还是通过反射处理的。

     private static void OnOpenWindowTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

    这是OpenWindowType属性的变更回调函数

    var type = GetOpenWindowType(d);
                if (type == null && type != typeof(Window))
                {
                    return;
                }
    
                Window window = Activator.CreateInstance(type) as Window;
    
                         if (window == null)
                         {
                             return;
                         }
                     
    
                     if (GetParameter(d) != null)
                     {
                         window.Tag = GetParameter(d);
                     }
    
                     var isModel = GetIsModal(d);
    
                     window.Closed += (win, closeArgs) =>
                     {
                         
                         window = null;
                     };
    
                     if (isModel)
                     {
                         window.ShowDialog();
                     }
                     else
                     {
                         window.Show();
                     }

    是吧,函数实现还是很简单的,看着明白了,那还少一点东西,什么呢? 怎么触发这个变更函数!

    在说触发的问题的时候,怎么想想怎么使用它

    attached:WindowHelper.IsModal="True"
                                        attached:WindowHelper.OpenWindowType="{x:Type local:Window1}"

    是吧,添加引用然后设置属性

    这个附加属性我们添加到哪里呢?当然是哪里用加哪里了。 所以可能是点击button弹窗,也可能是menuitem

    所以,我们要添加下面这段代码,在属性变更函数之前

    dynamic control = null;
                switch (d.GetType().Name.ToString())
                {
                    case "Button":
                        control = d as Button;
                        break;
    
                    case "Hyperlink":
                        control = d as Hyperlink;
                        break;
    
                    case "MenuItem":
                        control = d as MenuItem;
                        break;
    
                    default:
                        return;
                }
    var type = GetOpenWindowType(d);
                if (type == null && type != typeof(Window))
                {
                    return;
                }
    
                Window window = null;
                var clickEventHandler = new RoutedEventHandler((s, arg) =>
                 {
                     if (window == null)
                     {
                         window = Activator.CreateInstance(type) as Window;
    
                         if (window == null)
                         {
                             return;
                         }
                     }
    
                     if (GetParameter(d) != null)
                     {
                         window.Tag = GetParameter(d);
                     }
    
                     var isModel = GetIsModal(d);
    
                     window.Closed += (win, closeArgs) =>
                     {
                         
                         window = null;
                     };
    
                     if (isModel)
                     {
                         window.ShowDialog();
                     }
                     else
                     {
                         window.Show();
                     }
                 });
    
    
                control.Click += clickEventHandler;

    事实上,这个属性变更只会有一次,就是初始化的时候,所以我们在初始化的时候给按钮注册了事件,每次点击的时候去弹出窗体,做到这一步其实其他的就很好处理了,比如给vm传递参数,是不是用window.DataContext as VM,然后传递就可以了?当然更好的方式是写一个公共的接口,让VM去继承做处理。比如窗口关闭后需要调用某个函数做一些功能,是不是好实现多了,再加一个ICommand类型的附加属性不就可以了。

    分享就到这里,有更好的方案的同学可以加页面下方的群,欢迎讨论

  • 相关阅读:
    ZOJ 1002 Fire Net
    Uva 12889 One-Two-Three
    URAL 1881 Long problem statement
    URAL 1880 Psych Up's Eigenvalues
    URAL 1877 Bicycle Codes
    URAL 1876 Centipede's Morning
    URAL 1873. GOV Chronicles
    Uva 839 Not so Mobile
    Uva 679 Dropping Balls
    An ac a day,keep wa away
  • 原文地址:https://www.cnblogs.com/BeiJing-Net-DaiDai/p/11505733.html
Copyright © 2011-2022 走看看