使用Unity解析另一个视图中的用户控件视图

时间:2013-09-12 20:57:07

标签: c# wpf mvvm user-controls prism

我目前在我的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);
            }

1 个答案:

答案 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.DerperHerp类型的实例之间切换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}}

它看起来像什么:

enter image description here

毕竟,如果您仍想使用Unity来连接UI,您可以创建自己的DataTemplateSelector,使用Unity查找模板。浪费时间恕我直言。顺其自然。