اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
دو دقیقه
در نظر بگیرید که یک پروژه WPF را با الگوی MVVM پیاده سازی کرده اید و نیاز پیدا میکنید تا یک پنجره را از طریق کد ببندید. از آنجایی که به کنترل Window درون ViewModel دسترسی ندارید، نمیتوانید از متد Close آن برای اینکار استفاده کنید. راههای مختلفی برای اینکار وجود دارند، مثلا اگر از MVVM Light Toolkit استفاده میکنید با ارسال یک Message و نوشتن یک تکه کد در CodeBehind پنجره میتوانید اینکار را انجام بدهید.
اما برای اینکار یک راه حل سادهتری بدون نیاز به نوشتن کد در CodeBehind و استفاده از
Toolkit خاصی وجود دارد و آن استفاده ازخاصیتهای پیوست شده یا Attached Properties است. برای اینکار یک خاصیت از نوع Boolean مانند زیر تعریف میکنیم و آن را به پنجره ای که میخواهیم Colse شود پیوست میکنیم.
namespace TestProject.XamlServices { public class CloseBehavior { public static readonly DependencyProperty CloseProperty = DependencyProperty.RegisterAttached("Close", typeof(bool), typeof(CloseBehavior), new UIPropertyMetadata(false, OnClose)); private static void OnClose(DependencyObject sender, DependencyPropertyChangedEventArgs e) { if (!(e.NewValue is bool) || !((bool) e.NewValue)) return; var win = GetWindow(sender); if (win != null) win.Close(); } private static Window GetWindow(DependencyObject sender) { Window w = null; if (sender is Window) w = (Window)sender; return w ?? (w = Window.GetWindow(sender)); } public static bool GetClose(Window target) { return (bool)target.GetValue(CloseProperty); } public static void SetClose(DependencyObject target, bool value) { target.SetValue(CloseProperty, value); } } }
برای استفاده از این خصوصیت و اتصال آن باید یک خصوصیت از نوع Boolean نیز در ViewModel مربوط به Window ایجاد کنید:
private bool _isClose; public bool IsClose { get { return _isClose; } set { _isClose = value; OnClosed(); RaisePropertyChanged("IsClose"); } }
<Window x:Class="TestProject.TestView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:xamlServices="clr-namespace:TestProject.XamlServices;assembly=TestProject.XamlServices" xamlServices:CloseBehavior.Close="{Binding IsClose}"> ... </Window>