Tôi sử dụng hành vi được triển khai dưới dạng thuộc tính đính kèm. Nó có hai lợi thế chính so với System.Windows.Interactivity:
- nó có thể được xác định theo kiểu.
- mã XAML ít hơn nhiều trong quan điểm
trong trường hợp của bạn, quan điểm có thể trông giống như:
<UserControl ...
my:AttachedCommands.LoadedCommand="{Binding ViewLoadedCommand}">
Trong giải pháp của tôi, tôi không sử dụng các lệnh, nhưng tôi gọi các phương thức trên viewmodel nếu viewmodel thực hiện IViewModelLifeCycle
giao diện:
public interface IViewModelLifeCycle
{
void Activate(object extraData);
void Deactivate();
}
Tất cả các quan điểm của tôi sử dụng phong cách này:
0.123.
<Style x:Key="ViewBaseStyle">
<Setter Property="my:ViewModelLifeCycleBehavior.ActivateOnLoad" Value="True" />
và hành vi:
public static class ViewModelLifeCycleBehavior
{
public static readonly DependencyProperty ActivateOnLoadProperty = DependencyProperty.RegisterAttached("ActivateOnLoad", typeof (bool), typeof (ViewModelLifeCycleBehavior),
new PropertyMetadata(ActivateOnLoadPropertyChanged));
public static void SetActivateOnLoad(FrameworkElement element, bool value)
{
element.SetValue(ActivateOnLoadProperty, value);
}
public static bool GetActivateOnLoad(FrameworkElement element)
{
return (bool)element.GetValue(ActivateOnLoadProperty);
}
private static void ActivateOnLoadPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (DesignerProperties.GetIsInDesignMode(obj)) return;
var element = (FrameworkElement)obj;
element.Loaded -= ElementLoaded;
element.Unloaded -= ElementUnloaded;
if ((bool) args.NewValue == true)
{
element.Loaded += ElementLoaded;
element.Unloaded += ElementUnloaded;
}
}
static void ElementLoaded(object sender, RoutedEventArgs e)
{
var element = (FrameworkElement) sender;
var viewModel = (IViewModelLifeCycle) element.DataContext;
if (viewModel == null)
{
DependencyPropertyChangedEventHandler dataContextChanged = null;
dataContextChanged = (o, _e) =>
{
ElementLoaded(sender, e);
element.DataContextChanged -= dataContextChanged;
};
element.DataContextChanged += dataContextChanged;
}
else if (element.ActualHeight > 0 && element.ActualWidth > 0) //to avoid activating twice since loaded event is called twice on TabItems' subtrees
{
viewModel.Activate(null);
}
}
private static void ElementUnloaded(object sender, RoutedEventArgs e)
{
var element = (FrameworkElement)sender;
var viewModel = (IViewModelLifeCycle)element.DataContext;
viewModel.Deactivate();
}
}
TIP: Tạo custom Item Template trong Visual Studio cho Xem và ViewModel của bạn. nó rất dễ dàng và tiết kiệm rất nhiều thời gian. Mẫu mục có thể chứa mã xaml với trình kích hoạt/hành vi, trỏ đến kiểu cơ sở của bạn, định nghĩa d:DataContext
và lớp chế độ xem của bạn.
Tại sao không tạo kiểu với khóa? –
@Nikita Thực ra, tôi không biết cách tạo ra một kiểu đặt các thuộc tính đính kèm phức tạp và phức tạp như 'Tương tác.Trích ứng'. – Dai
ViewLoadedCommand nằm ở đâu? Đây có phải là trong mô hình xem của bạn không? Bạn có chắc chắn muốn gọi lệnh này ** mỗi lần ** điều khiển người dùng được tải không? –