如何在C#MVVM

时间:2017-02-02 05:19:29

标签: c# wpf mvvm reflection caliburn.micro

在WPF MVVM(Caliburn Micro)应用程序中,我有一个空ViewModel和一个空视图。 (视图模型没有任何属性,视图没有任何字段。)

  

CommonView(CommonView.cs)

     

CommonViewModel(CommonView.xaml - UserControl)

需要动态地向视图和ViewmModel添加属性和字段。

我在PropertyInfo对象中有一个属性列表。基于PropertyInfo,我需要在运行时动态地向ViewModel添加属性。

  1. 可能吗?任何人都可以用一些代码样本来解释这个吗?
  2. 是否可以动态实现INotifyPropertyChange 添加了属性?
  3. 更新

    我也有一个Model类,我有属性。其中很少用自定义属性装饰。

    通过使用反射,我可以获得使用自定义属性修饰的属性(PropertyInfo)。 例如:

    var props = t.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(CustomAttribute)));
    

    现在我想在运行时将这些属性添加到ViewModel。这是实际要求。

    例如:

    public class CommonViewModel: Screen
    { 
       //Below properties needs to be added dynamically during the runtime
       Public string Prop1{get;set;}
       Public string Prop2{get;set;}
       Public string Prop3{get;set;}
    }
    

1 个答案:

答案 0 :(得分:1)

对我的评论的解释:

在主视图中:

<ItemsControl ItemsSource="{Binding ProperyList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ContentControl Content="{Binding }"/></DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

用于字符串属性的UserControl(为每个类型创建一个):

<UserControl x:Class="UI.Views.StringView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
            <DockPanel>
                <TextBlock Text="{Binding PropertyName}"></TextBlock>
                <TextBox Text="{Binding Value}"></TextBox>
            </DockPanel>
    </Grid>
</UserControl>

属性的ViewModels(为每种类型创建一个,可能它可以更通用,在这里你也可以实现INotifyPropertyChanged):

public class StringPropertyViewModel
{
    public string PropertyName;
    public string Value;
}

public class DateTimePropertyViewModel
{
    public string PropertyName;
    public DateTime Value;
}

的App.xaml:

<DataTemplate DataType="{x:Type StringPropertyViewModel}">
    <StringView />
</DataTemplate>

<DataTemplate DataType="{x:Type DateTimePropertyViewModel}">
    <DateTimeView />
</DataTemplate>

在CommonViewModel中,您可以拥有列表:

public ObservableCollection<object> ProperyList {get; set;}

这不是你需要的吗?

<强>更新

如何填充ProperyList的示例:

例如,类StringPropertyViewModel可以像这样实现:

public class StringPropertyViewModel
{
    public object Model { get; set; }
    public string PropertyName { get; set; }
    public PropertyInfo Property { get; set; }

    public string Value
    {
        get { return (string)Property.GetValue(Model); }
        set 
          {
              Property.SetValue(Model, value);
              RaisePropertyChanged(x => nameof(Value));
          }
    }
}

然后在这里填写主(空)ViewModel

的列表
YourModelType m;
//... set m to an instance of your model

var props = t.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(CustomAttribute)));

foreach (var p in props)
{
    var vm = new StringPropertyViewModel();
    vm.Property = p;
    vm.Model = m;
    ProperyList.Add(vm);
}