我目前在我的wpf应用程序中使用带有PRISM的MVVM模式,并将Shell,Views和ViewModel全部注入并绑定在一起。 (据我所知......这是我的第一个wpf应用程序)。我的模块定义正确连接所有内容。
我必须在我的一个视图上显示不一致大小的对象集合,而不是在后端手动创建它,我想创建一个新的用户控件并将其绑定到单个数据实体,以便我可以保持自我认知和管理,但这些控件需要添加到我的视图中的网格或面板。按照前面的例子,我决定沿着界面+混凝土路径走下去,以便保持小块的灵活性。
首先,我是否正确地走这条路?在ASP.Net中,我将为显示创建一个模板,然后附加模型。
第二,在我构建主视图时,是否有一种可接受的方法让我的容器解析这个“模板”用户控件?
最初我的代码看起来是这样的,所以我想用另一个xaml完全替换它:
foreach (var node in nodes) {
var p = new StackPanel();
p.DataContext = node;
p.Children.Add(new Label() { Content = node.Name });
p.Children.Add(new TextBox() { Text = "" });
NodesControl.Children.Add(p);
}
答案 0 :(得分:2)
让DataTemplates为您完成工作。
给定一个简单的窗口,使用以下ViewModel:
public sealed class ViewModel : INotifyPropertyChanged
{
private object _derper;
public event PropertyChangedEventHandler PropertyChanged = (o, e) => { };
public object Derper
{
get { return this._derper; }
set
{
this._derper = value;
PropertyChanged(this, new PropertyChangedEventArgs("Derper"));
}
}
public ICommand OnDerp { get; set; }
public ViewModel()
{
OnDerp = new DerpCommand(this);
}
}
我们希望为属性Derper的不同值显示不同的UI。此属性由DerpCommand设置:
public sealed class DerpCommand : ICommand
{
public event EventHandler CanExecuteChanged;
private readonly ViewModel _viewModel;
private int _count = 0;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_viewModel.Derper = _count % 2 == 0 ?
(object)new Derp()
{ Herp = "Derped " + (++_count / 2 + 1) + " times." } :
new Herp()
{ Derp = "Herped " + (_count++ / 2 + 1) + " times." };
}
public DerpCommand(ViewModel viewModel)
{
this._viewModel = viewModel;
}
}
它只是根据运行的次数在ViewModel.Derper
和Herp
类型的实例之间切换Derp
的值。我将省略这些模型的实现,因为它们是具有单个属性的POCO。沉闷的东西。
现在,当ViewModel.Derper
属性类型为Derp
时,我们需要一个漂亮的矢车菊蓝色背景,黑色文本前景显示模型的值。当它是Herp
类型时,我们想要一个带有白色文本的黑色背景。因此,我们为每个人创建DataTemplates
:
<DataTemplate
DataType="{x:Type t:Derp}">
<TextBlock
Padding="50"
Background="CornflowerBlue"
Text="{Binding Herp}" />
</DataTemplate>
<DataTemplate
DataType="{x:Type t:Herp}">
<TextBlock
Padding="50"
Foreground="White"
Background="Black"
Text="{Binding Derp}" />
</DataTemplate>
请注意,在每个DataTemplate
DataContext
中,DataType
是指定DataTemplate
模型的实例。
我们如何连接它们?我们没有。我们只需在UI中指定我们希望通过添加ContentControl
并将其Content
属性绑定到ViewModel.Derper
来显示相应<Window
x:Class="DataTemplateExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:t="clr-namespace:DataTemplateExample"
Title="DataTemplate example"
Height="350"
Width="525">
<Window.DataContext>
<t:ViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate
DataType="{x:Type t:Derp}">
<TextBlock
Padding="50"
Background="CornflowerBlue"
Text="{Binding Herp}" />
</DataTemplate>
<DataTemplate
DataType="{x:Type t:Herp}">
<TextBlock
Padding="50"
Foreground="White"
Background="Black"
Text="{Binding Derp}" />
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition
Height="auto" />
</Grid.RowDefinitions>
<ContentControl
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{Binding Derper}" />
<Button
Grid.Row="1"
Command="{Binding OnDerp}">Click me to derp</Button>
</Grid>
</Window>
的区域。这是整个用户界面:
{{1}}
它看起来像什么:
毕竟,如果您仍想使用Unity来连接UI,您可以创建自己的DataTemplateSelector
,使用Unity查找模板。浪费时间恕我直言。顺其自然。