在 WPF/MVVMLight 应用程序中创建依赖项 属性 的指导
Guidance in creating a dependency property in WPF/MVVMLight application
我有一个 WPF/MVVMLight 应用程序。我的主要 view/viewmodel 有一个数据网格,代码隐藏在视图模型中。我最近决定我要
这个数据网格在第二个视图中,一个视图是实时数据,一个视图显示相同数据的历史记录。我不想在两个地方复制这段代码,所以我决定创建一个带有视图模型的用户控件,并将适当的 datagrid/code 移动到用户控件。
这是 issue/question:我想在我的主视图模型中将 usercontrol->datagrid->itemsource 设置为 属性。我见过一些人们创建依赖属性的例子,但我不确定如何处理这个,因为我不能在我的视图模型中继承 DependencyObject,因为它已经继承了 ViewModelBase(来自 mvvm light),所以我不能使用 GetValue/SetValue 如下所示。我对此很陌生,所以我可能会遗漏一些非常明显的东西。在寻找我的问题的解决方案时,我看到 MVVM Light 具有一些消息传递功能,这是解决这个问题的更好方法吗?有没有比我正在采取的更好的方法?感谢您的指导。
示例不是从我的代码中提取的,只是用来展示我不知道如何使用的 GetValue/SetValue,因为我无法继承 DependencyObject。
public class MyViewModel : ViewModelBase
{
public static DependencyProperty MyProperty =
DependencyProperty.Register("GridItemSource", typeof(EventData), typeof(MyViewModel),
new FrameworkPropertyMetadata() { BindsTwoWayByDefault = true });
public EventData GridItemSource
{
get { return (EventData)GetValue(MyProperty); }
set { SetValue(MyProperty, value); }
}
--- 试图更清楚地了解我希望实现的目标..
下面是我的用户控件中的数据网格示例。我的用户控件有一个带有代码隐藏的 VM,其中包含您在下面看到的绑定的属性以及一些与上下文菜单相关的附加代码。
我要解决的问题是如何设置 usercontrol datagrid itemsource,因为它位于嵌套在我的主视图中的 usercontrol 中,并且最终将嵌套在另一个视图中。我的主视图有一个 ObservableCollection,其中包含我想要 usercontrol/datagrid/itemsource 设置的数据。我的想法是我可以在我的主视图可以用来设置源的用户控件中创建一个依赖项 属性。
所以在我添加用户控件的主视图中,我想做这样的事情:
<Views:MyUserControl SomePropertyInUserControl="{Binding MyObservableCollection, Mode=TwoWay}"/>
在我的用户控制视图中:
<DataGrid Grid.Row="0" SelectedItem="{Binding DataGridSelectedItem, Mode=TwoWay}" HeadersVisibility="All" HorizontalAlignment="Stretch" Name="lbMain" ItemsSource="{Binding MonitorEventItems, Mode=TwoWay}" AutoGenerateColumns="False" SelectionMode="Single" >
<DataGrid.ContextMenu>
<ContextMenu ItemsSource="{Binding ContextMenuEventList,Mode=Default}"/>
</DataGrid.ContextMenu>
<DataGrid.Columns>
<DataGridTextColumn Header="Date" Binding="{Binding EventDateTime}" Width="Auto"/>
<DataGridTextColumn Header="Event Type" Binding="{Binding EventType}" Width="Auto"/>
<DataGridTextColumn Header="Folder/File" Binding="{Binding FFType}" Width="Auto"/>
<DataGridTextColumn Header="Name" Binding="{Binding EventFileFolderName}" Width="Auto"/>
<DataGridTextColumn Header="Full Path" Binding="{Binding EventFileFolderFullPath}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
不要在视图模型中使用依赖属性。它们与普通属性的主要区别在于可以通过绑定、样式、动画等进行设置,而这些在视图模型中是不需要的。
相反,创建一个 属性 引发 INotifyPropertyChanged
接口的 PropertyChanged
事件,该事件由 ViewModelBase class 实现。此外,使用 ObservableCollection
作为 属性 类型,以通知 Items 集合中的更改。
public class MyViewModel : ViewModelBase
{
private ObservableCollection<DataItem> items;
public ObservableCollection<DataItem> Items
{
get { return items; }
set
{
items = value;
RaisePropertyChanged("Items");
}
}
}
同样的问题已解决 。 (注意:不使用依赖属性)使用 EventHandler 处理此问题并使用 MVVM Light Messaging 的示例。线程中的其他可能 solutions/answers。
我有一个 WPF/MVVMLight 应用程序。我的主要 view/viewmodel 有一个数据网格,代码隐藏在视图模型中。我最近决定我要 这个数据网格在第二个视图中,一个视图是实时数据,一个视图显示相同数据的历史记录。我不想在两个地方复制这段代码,所以我决定创建一个带有视图模型的用户控件,并将适当的 datagrid/code 移动到用户控件。
这是 issue/question:我想在我的主视图模型中将 usercontrol->datagrid->itemsource 设置为 属性。我见过一些人们创建依赖属性的例子,但我不确定如何处理这个,因为我不能在我的视图模型中继承 DependencyObject,因为它已经继承了 ViewModelBase(来自 mvvm light),所以我不能使用 GetValue/SetValue 如下所示。我对此很陌生,所以我可能会遗漏一些非常明显的东西。在寻找我的问题的解决方案时,我看到 MVVM Light 具有一些消息传递功能,这是解决这个问题的更好方法吗?有没有比我正在采取的更好的方法?感谢您的指导。
示例不是从我的代码中提取的,只是用来展示我不知道如何使用的 GetValue/SetValue,因为我无法继承 DependencyObject。
public class MyViewModel : ViewModelBase
{
public static DependencyProperty MyProperty =
DependencyProperty.Register("GridItemSource", typeof(EventData), typeof(MyViewModel),
new FrameworkPropertyMetadata() { BindsTwoWayByDefault = true });
public EventData GridItemSource
{
get { return (EventData)GetValue(MyProperty); }
set { SetValue(MyProperty, value); }
}
--- 试图更清楚地了解我希望实现的目标..
下面是我的用户控件中的数据网格示例。我的用户控件有一个带有代码隐藏的 VM,其中包含您在下面看到的绑定的属性以及一些与上下文菜单相关的附加代码。
我要解决的问题是如何设置 usercontrol datagrid itemsource,因为它位于嵌套在我的主视图中的 usercontrol 中,并且最终将嵌套在另一个视图中。我的主视图有一个 ObservableCollection,其中包含我想要 usercontrol/datagrid/itemsource 设置的数据。我的想法是我可以在我的主视图可以用来设置源的用户控件中创建一个依赖项 属性。
所以在我添加用户控件的主视图中,我想做这样的事情:
<Views:MyUserControl SomePropertyInUserControl="{Binding MyObservableCollection, Mode=TwoWay}"/>
在我的用户控制视图中:
<DataGrid Grid.Row="0" SelectedItem="{Binding DataGridSelectedItem, Mode=TwoWay}" HeadersVisibility="All" HorizontalAlignment="Stretch" Name="lbMain" ItemsSource="{Binding MonitorEventItems, Mode=TwoWay}" AutoGenerateColumns="False" SelectionMode="Single" >
<DataGrid.ContextMenu>
<ContextMenu ItemsSource="{Binding ContextMenuEventList,Mode=Default}"/>
</DataGrid.ContextMenu>
<DataGrid.Columns>
<DataGridTextColumn Header="Date" Binding="{Binding EventDateTime}" Width="Auto"/>
<DataGridTextColumn Header="Event Type" Binding="{Binding EventType}" Width="Auto"/>
<DataGridTextColumn Header="Folder/File" Binding="{Binding FFType}" Width="Auto"/>
<DataGridTextColumn Header="Name" Binding="{Binding EventFileFolderName}" Width="Auto"/>
<DataGridTextColumn Header="Full Path" Binding="{Binding EventFileFolderFullPath}" Width="*"/>
</DataGrid.Columns>
</DataGrid>
不要在视图模型中使用依赖属性。它们与普通属性的主要区别在于可以通过绑定、样式、动画等进行设置,而这些在视图模型中是不需要的。
相反,创建一个 属性 引发 INotifyPropertyChanged
接口的 PropertyChanged
事件,该事件由 ViewModelBase class 实现。此外,使用 ObservableCollection
作为 属性 类型,以通知 Items 集合中的更改。
public class MyViewModel : ViewModelBase
{
private ObservableCollection<DataItem> items;
public ObservableCollection<DataItem> Items
{
get { return items; }
set
{
items = value;
RaisePropertyChanged("Items");
}
}
}
同样的问题已解决