嗯。。最近回家去了,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類型的附加屬性不就可以了。
分享就到這里,有更好的方案的同學可以加頁面下方的群,歡迎討論
