绑定到模型属性不起作用

时间:2014-11-07 16:23:26

标签: c# wpf mvvm data-binding caliburn.micro

我需要将域模型的属性值(加载到视图模型中)绑定到shell视图上的控件内容,但它根本不工作(内容保持空白)。我怎样才能解决这个问题?域模型是否也需要实现INotifyPropertyChanged?

ShellViewModel

public class ShellViewModel : Conductor<ProjectViewModel>.Collection.OneActive, IShell
{

    public ShellViewModel() {
        ActivateItem(new ProjectViewModel(new Project { ProjectName = "Test" }));
    }

}

ShellView(标签控件)

<TabControl x:Name="Items">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding ActiveItem.Project.ProjectName}" />
            </DataTemplate>
        </TabControl.ItemTemplate>
</TabControl>

ProjectViewModel

public class ProjectViewModel : Screen
{

    private Project _project;

    public Project Project
    {
        get { return _project; }
        private set
        {
            _project = value;
            NotifyOfPropertyChange(() => _project);
        }
    }

    public ProjectViewModel(Project project)
    {
        Project = project;
    }    

项目

public class Project
{

    public string ProjectName { get; set; }

}

2 个答案:

答案 0 :(得分:1)

如果你想使用绑定,那么你绑定的属性的对象必须实现INotifyPropertyChanged。否则你只看到初始值。所以是的,简单的方法是你的域模型实现INotifyPropertyChanged。

   <TextBlock Text="{Binding ActiveItem.Project.ProjectName}" />

使用此行wpf不关心OnPropertyChanged(&#34; Project&#34;)因为它绑定到ProjectName。

答案 1 :(得分:0)

没有你的Conductor.Collection是类型ProjectViewModel使它成为Screen或IScreen,因为ProjectViewModel继承了Screen是最好的选择。完成后,在ShellViewModel的构造函数中执行集合调用。

shellviewmodel 将如下所示。

public ShellViewModel(/*IEnumerable<Screen> screens*/){  // Not Necessary 

     //automatically finds what is in the IoC Container 
     //(MEF, SimpleContainer, AutoFac, StructureMap etc... 
     //Assuming your using one...

     //this.Items.AddRange(screens);
      this.Items.Add(new ProjectViewModel(new Project(){ ProjectName = "Test";}));   
}
protected override OnInitialize(){

}

<强>模板

<TabControl x:Name="Items">
    <TabControl.ItemTemplate>
        <DataTemplate>
          <StackPanel>
              <TextBlock Text="{Binding DisplayName}" />
              <TextBlock Text="{Binding Project.ProjectName}" /> 
          </StackPanel>                     
        </DataTemplate>
 </TabControl.ItemTemplate>

我做DisplayName的原因是它已经在Screen的类对象中作为属性......这样你就不必做太多额外的工作,编写你的ViewModels。 / p>

public class ProjectViewModel : Screen{
  private Project _project;
  public ProjectViewModel(Project project){

    DisplayName = "Test" ;

    Project = project;
  }  
  public Project Project{
       get{ return _project;}
       private set{
           _project = value;
           NotifyOfPropertyChange();
       }
    }
 }

在您要显示的模型对象上将继承PropertyChangedBase

在ViewModel上,它们将继承PropertyChangedBased,Screen或甚至Conductor(例如)。所有人都有不同的需求,以适应你想做的事情。

要看的另一件事是项目中的IoC容器实际上有2个。 1 SimpleContainer 2 MEF,大多数(如果不是全部)样本都使用MEF。