【发布时间】:2018-07-18 23:55:02
【问题描述】:
我正在做一个项目,我有三个 ViewModel: ObjectDetailsViewMode 有一个 ObjectBase 类型的上下文(属性链接到一个模型); PropertyTextViewModel 有一个 PropertyText 类型的 Context,PropertyNumberViewModel 有一个 PropertyNumber 类型的 Context。
以下是模型的结构:
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); }
}
}
关于视图,我对每个 ViewModel 都有一个。 ObjectDetailsView 是一个使用控件,它有一个用于编辑 Object.Name 的 TextBox、两个用于向 Object.Properties 添加新的 PropertyText/PropertyNumber 的按钮以及一个连接到该 Object.Properties 的 ItemsControl。
ItemsControl (ItemsSource) 中的每个 PropertyBase 都使用 DataTemplate 标记解析为一个新视图:
<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,然后将视图 DataContext 设置为新的 ViewModel。我的问题是我需要将 Object.Properties 列表中的新属性传递给新创建的 View 的 ViewModel 并将其存储在我那里的 Context 属性中。
我无法避免为每种属性类型创建一个 View/ViewModel,因为某些属性类型(不是我在此处描述的类型)有一些底层逻辑。但我还有其他类型,如 Boolean、Reference、枚举...)
所以我真的需要向我尝试使用的 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));
我应该可以做到:
对吗?!为什么没有调用公共属性“Context”(我在那里放置了一个断点,但什么也没有得到)。
【问题讨论】:
-
尝试将其设置为:
加上句号 -
@Unlockedluca 我试过了..但不起作用..当我创建实例时,ViewModel 中的 GET 方法被调用(不知道为什么)但 SET 方法没有://
-
您的自定义上下文属性的类是否实现了 INotifyPropertyChanged?
-
@Unlockedluca 它实现了 BindableBase,它是 PRISM 中的一个基类,作为 INotifyPropertyChanged
-
如果你添加例如它是否工作:
然后TextBlock 中显示的文本正确吗?