我正在做一个项目,我有三个 ViewModel: ObjectDetailsViewMode 有一个 ObjectBase 类型的上下文(属性链接到模型); PropertyTextViewModel 有一个PropertyText 类型的上下文,而PropertyNumberViewModel 有一个PropertyNumber 类型的上下文。
下面是模型的结构:
public class ObjectBase : ModelBase
{
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value); }
}
public DataCollection<PropertyBase> Properties { get; } = new DataCollection<PropertyBase>();
}
public class PropertyText : PropertyBase
{
private string _default;
public string Default
{
get { return _default; }
set { SetProperty(ref _default, value); }
}
}
public class PropertyNumber : PropertyBase
{
private double _default = 0;
public double Default
{
get { return _default; }
set { SetProperty(ref _default, value); }
}
private double _minValue = 0;
public double MinValue
{
get { return _minValue; }
set { SetProperty(ref _minValue, value); }
}
private double _maxValue = 0;
public double MaxValue
{
get { return _maxValue; }
set { SetProperty(ref _maxValue, value); }
}
}
关于 View ,我对每个 ViewModel 都有一个。 ObjectDetailsView 是一个使用控件,它具有一个用于编辑 Object.Name 的 TextBox、两个用于将新 PropertyText/PropertyNumber 添加到 Object.Properties 的按钮以及一个连接到该 Object.Properties 的 ItemsControl。
ItemsControl (ItemsSource) 中的每个 PropertyBase 都使用 DataTemplate 标记解析为一个新 View :
<ItemsControl ItemsSource="{Binding Object.Properties}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type models:PropertyText}">
<views:PropertyTextView />
</DataTemplate>
<DataTemplate DataType="{x:Type models:PropertyNumber}">
<views:PropertyNumberView />
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
当我使用 PRISM 时,会自动为我创建正确的 ViewModel,然后将 View DataContext 设置为新的 ViewModel。我的问题是我需要将 Object.Properties 列表中的新属性传递给新创建的 View 的 ViewModel 并将其存储在我在那里的 Context 属性中。
我无法避免为每种属性类型创建一个 View / View 模型,因为某些属性类型(不是我在这里描述的类型)有一些底层逻辑。但我还有其他类型,如 bool 、引用、枚举。 .)
所以我真的需要将一个值传递给我尝试使用的 ViewModel
<ItemsControl ItemsSource="{Binding Object.Properties}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type models:PropertyText}">
<views:PropertyTextView Context="{Binding}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type models:PropertyNumber}">
<views:PropertyNumberView Context="{Binding}"/>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
请注意,Context 是我在 ViewModel 中创建的用于存储 ModelContext 的自定义属性。我什至在 View 的后台代码中创建了一个 DependencyProperty:
public PropertyBase Context
{
get { return (PropertyBase)GetValue(ContextProperty); }
set { SetValue(ContextProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ContextProperty =
DependencyProperty.Register("Context", typeof(PropertyBase), typeof(PropertyTextView), new PropertyMetadata(null));
但它没有链接到 ViewModels 设置事件(我在那里做了一个断点......什么都没有)。我什至在 PropertyTextView 代码隐藏(构造函数)中尝试了 SetBinding:
string propertyInViewModel = "Context";
var bindingViewMode = new Binding(propertyInViewModel) { Mode = BindingMode.TwoWay };
this.SetBinding(ContextProperty, bindingViewMode);
这些都没有运气......我真的卡住了。
更简单的东西
如果 PropertyTextView 有这个依赖属性。
public string Context
{
get { return (PropertyBase)GetValue(ContextProperty); }
set { SetValue(ContextProperty, value); }
}
// Using a DependencyProperty as the backing store for Context. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ContextProperty =
DependencyProperty.Register("Context", typeof(string), typeof(PropertyTextBuilderView), new PropertyMetadata(null));
我应该能够做到:
对?!为什么不调用公共(public)属性“上下文”(我在那里放置了一个断点,但什么也没得到)。
最佳答案
而不是仅仅设置Context
您的 View 属性为新的 Binding
您需要分配当前 DataContext
像这样:<views:PropertyNumberView Context="{Binding .}"/>
这应该分配当前 Views.DataContext
属性到您的新 View 。
如果您在 DataTemplate 中,您可能需要指定 RelativeSource
:<views:PropertyNumberView Context="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType=UserControl}}
<ItemsControl ItemsSource="{Binding Object.Properties}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type models:PropertyText}">
<views:PropertyTextView Context="{Binding .}"/>
</DataTemplate>
<ItemsControl.Resources>
</ItemsControl>
关于c# - 在 UserControls( View )MVVM Prism 之间传递 ModelData(上下文),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48685038/