C# 在usercontrol中设置usercontrol的datacontext,无论usercontrol有多少层
我目前正在创建一个测试WPF灵活性的应用程序。我有一些usercontrols,当涉及到它的ViewModel时,它们是非常透明的。我所说的透明是指,只要ViewModel具有绑定到该usercontrol中的控件的所有必需属性,usercontrol就可以使用任何类型的ViewModel。为此,我将ViewModel指定为特定usercontrol的datacontext 当只有两个UserControl(一个可以访问ViewModelLocator,另一个需要来自前者的datacontext声明)时,这就可以工作了。我不知道当它达到3层或更多的用户控件时该怎么办。是否有方法在usercontrol中设置usercontrol的datacontext,该usercontrol位于可以访问ViewModelLocator的usercontrol中 下面是一些代码,可以澄清我的问题 此代码是父用户控件。它旨在用于使用MAF的应用程序。我使用了一个非静态的ViewModelLocator来确保每个插件实例使用不同的ViewModelLocator实例,因为插件没有自己的app.xaml(因此没有全局资源)。如您所见,我在网格中放置了来自单独程序集的usercontrol,然后声明了其datacontext,以便所述usercontrol将与父usercontrol的ViewModelLocator交互C# 在usercontrol中设置usercontrol的datacontext,无论usercontrol有多少层,c#,wpf,mvvm,user-controls,mvvm-light,C#,Wpf,Mvvm,User Controls,Mvvm Light,我目前正在创建一个测试WPF灵活性的应用程序。我有一些usercontrols,当涉及到它的ViewModel时,它们是非常透明的。我所说的透明是指,只要ViewModel具有绑定到该usercontrol中的控件的所有必需属性,usercontrol就可以使用任何类型的ViewModel。为此,我将ViewModel指定为特定usercontrol的datacontext 当只有两个UserControl(一个可以访问ViewModelLocator,另一个需要来自前者的datacontext
<UserControl x:Class="TestApp.Inventory.Common.Views.MaterialsNewView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:vm="clr-namespace:TestApp.Inventory.Common.ViewModel"
xmlns:views="clr-namespace:TestApp.Inventory.Common.Views"
xmlns:viewsSupp="clr-namespace:TestApp.Supplier.Common.Views;assembly=TestApp.Supplier.Common"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="607" Width="616" Loaded="UserControl_Loaded">
<UserControl.Resources>
<vm:ViewModelLocator x:Key="Locator" />
</UserControl.Resources>
<UserControl.DataContext>
<Binding Path="MaterialsNewView" Source="{StaticResource Locator}" />
</UserControl.DataContext>
<Grid>
<views:SupplierView x:Name="supplierView" Margin="145,306,0,0" HorizontalAlignment="Left" Width="328" Height="258" VerticalAlignment="Top" DataContext="{Binding Source={StaticResource Locator}, Path=SupplierView}" />
</Grid>
</UserControl>
然后我有了子用户控件的代码。正如我前面所说的,子用户控件在ViewModel方面是透明的。这就是每次都应该在父用户控件中声明datacontext的原因
<UserControl x:Class="TestApp.Supplier.Common.Views.SupplierView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.ignore.com"
mc:Ignorable="d ignore" Height="289" Width="352"
xmlns:my="clr-namespace:TestApp.Lookup.Common.Views;assembly=TestApp.Lookup.Common">
<Grid>
<my:MaterialTypeListView Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualHeight}" HorizontalAlignment="Left" Name="materialTypeListView1" VerticalAlignment="Top" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualWidth}" />
</Grid>
</UserControl>
我的问题是当子用户控件有自己的子用户控件时。我不知道如何从父用户控件声明其datacontext。目标是,无论用户控件有多少层,它们都应该与父用户控件的ViewModelLocator交互。向名为MaterialTypeList的usercontrol SupplierView添加一个
DependencyProperty
public partial class SupplierView
{
public List<string> MaterialTypeList
{
get { return (List<string>)GetValue(MaterialTypeListProperty); }
set { SetValue(MaterialTypeListProperty, value);}
}
public static readonly DependencyProperty MaterialTypeListProperty =
DependencyProperty.Register("MaterialTypeList", typeof(string), typeof(SupplierView),
new PropertyMetadata(null));
}
<UserControl x:Class="TestApp.Inventory.Common.Views.MaterialsNewView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:vm="clr-namespace:TestApp.Inventory.Common.ViewModel"
xmlns:views="clr-namespace:TestApp.Inventory.Common.Views"
xmlns:viewsSupp="clr-namespace:TestApp.Supplier.Common.Views;assembly=TestApp.Supplier.Common"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="607" Width="616" Loaded="UserControl_Loaded">
<UserControl.Resources>
<vm:ViewModelLocator x:Key="Locator" />
</UserControl.Resources>
<UserControl.DataContext>
<Binding Path="MaterialsNewView" Source="{StaticResource Locator}" />
</UserControl.DataContext>
<Grid>
<views:SupplierView x:Name="supplierView" Margin="145,306,0,0"
MaterialTypeList="{Binding [HERE YOUR LIST OF MATERIALTYPE]}"
HorizontalAlignment="Left" Width="328" Height="258" VerticalAlignment="Top" DataContext="{Binding Source={StaticResource Locator}, Path=SupplierView}" />
</Grid>
</UserControl>
公共部分类供应商视图
{
公共列表材料类型列表
{
获取{return(List)GetValue(MaterialTypeListProperty);}
set{SetValue(MaterialTypeListProperty,value);}
}
公共静态只读从属属性MaterialTypeListProperty=
DependencyProperty.Register(“材料类型列表”、类型(字符串)、类型(供应商视图),
新属性元数据(空);
}
将UserControl MaterialNewView供应商视图上的绑定添加到MaterialTypeList
<UserControl x:Class="TestApp.Supplier.Common.Views.SupplierView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.ignore.com"
mc:Ignorable="d ignore" Height="289" Width="352"
xmlns:my="clr-namespace:TestApp.Lookup.Common.Views;assembly=TestApp.Lookup.Common">
<Grid>
<my:MaterialTypeListView
DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl, AncestorLevel=1}, Path=MaterialTypeList}"
Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualHeight}" HorizontalAlignment="Left" Name="materialTypeListView1" VerticalAlignment="Top" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Grid, AncestorLevel=1}, Path=ActualWidth}" />
</Grid>
</UserControl>
将MaterialTypeListView上的UserControl SupplierView上的绑定添加到MaterialTypeList
public partial class SupplierView
{
public List<string> MaterialTypeList
{
get { return (List<string>)GetValue(MaterialTypeListProperty); }
set { SetValue(MaterialTypeListProperty, value);}
}
public static readonly DependencyProperty MaterialTypeListProperty =
DependencyProperty.Register("MaterialTypeList", typeof(string), typeof(SupplierView),
new PropertyMetadata(null));
}
<UserControl x:Class="TestApp.Inventory.Common.Views.MaterialsNewView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:vm="clr-namespace:TestApp.Inventory.Common.ViewModel"
xmlns:views="clr-namespace:TestApp.Inventory.Common.Views"
xmlns:viewsSupp="clr-namespace:TestApp.Supplier.Common.Views;assembly=TestApp.Supplier.Common"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="607" Width="616" Loaded="UserControl_Loaded">
<UserControl.Resources>
<vm:ViewModelLocator x:Key="Locator" />
</UserControl.Resources>
<UserControl.DataContext>
<Binding Path="MaterialsNewView" Source="{StaticResource Locator}" />
</UserControl.DataContext>
<Grid>
<views:SupplierView x:Name="supplierView" Margin="145,306,0,0"
MaterialTypeList="{Binding [HERE YOUR LIST OF MATERIALTYPE]}"
HorizontalAlignment="Left" Width="328" Height="258" VerticalAlignment="Top" DataContext="{Binding Source={StaticResource Locator}, Path=SupplierView}" />
</Grid>
</UserControl>
感谢您的快速回复。但是,这两个用户控件使用不同的视图模型。我希望MaterialTypeListView能够与MaterialsNewView访问的ViewModelLocator进行通信,以获取任何适用于它的ViewModel,如果可能,还可以从MaterialsNewView声明其绑定。更改了我的答案。简而言之,在uc:Supplier视图中添加DependencyProperty,您可以将materialtypelist绑定到该视图。很抱歉,我是WPF的新手,我不太明白DependencyProperty如何解决我的问题。如果可能的话,你能详细说明一下并提供示例代码吗?非常感谢。是的,现在说得通了。我一回到办公室就试试,然后再给你打电话。成功了!我已经找了好几天了。这很有魅力。你真棒!非常感谢D