我在项目上工作并且我有三个ViewModel:ObjectDetailsViewMode有一个ObjectBase类型的Context(链接到模型的属性); 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是一个use控件,它有一个用于编辑Object.Name的TextBox,两个用于向Object.Properties添加新PropertyText / PropertyNumber的按钮和一个连接到该Object.Properties的ItemsControl。
使用DataTemplate标记将ItemsControl(ItemsSource)中的每个PropertyBase解析为一个新视图:
<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。我的问题是我需要将新的Property从Object.Properties列表传递给新创建的View的ViewModel,并将其存储在我所拥有的Context属性中。
我无法避免为每种属性类型创建一个View / ViewModel,因为在某些Property类型上有一些底层逻辑(不是我在这里描述的那些..但我有其他类型,如Boolean,参考,枚举...)
所以我真的需要将值传递给我试图使用的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。我甚至在视图后面的代码中创建了一个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);
这些都没有运气......我&#39;真的卡住了。
更简单的事情
如果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));
我应该可以这样做:
右?为什么不是公共财产&#34; Context&#34;没有被叫(我在那里放了一个断点而我什么都没得到。)
答案 0 :(得分:0)
您不需要将视图的Context
属性设置为新的Binding
,而是需要像这样分配当前DataContext
:
<views:PropertyNumberView Context="{Binding .}"/>
这应该将当前Views.DataContext
属性分配给您的新视图。
如果您在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>
答案 1 :(得分:0)
当我使用PRISM时,会自动为我创建正确的ViewModel
你没有 使用Prism的view-first。如果您选择ViewModelLocator
可以提供帮助,但也可以查看模型优先。
如果我理解正确,您有一个视图模型,并希望使用子视图模型填充列表。就这样做:
internal class ParentViewModel : BindableBase
{
public ParentViewModel( ParentModel parentModel, IChildViewModelFactory factory )
{
Children = new object[] { factory.CreateTextViewModel(parentModel.TextProperty), factory.CreateNumberViewModel(parentModel.NumberProperty) };
}
public IEnumerable Children { get; }
}
并通过DataTemplate
s将不同的子视图模型映射到子视图。
parentModel.WhateverProperty
会有Name
和Value
属性以及值的设置者,可能......