绑定到模型属性不起作用

本文关键字:不起作用 属性 模型 绑定 | 更新日期: 2023-09-27 18:29:46

我需要将域模型的属性值(加载到视图模型中)绑定到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; }
}

绑定到模型属性不起作用

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

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

wpf不关心OnPropertyChanged("Project"),因为它绑定到ProjectName。

不要使用Conductor。集合的类型应为ProjectViewModel,使其成为Screen或IScreen,因为ProjectViewModel继承了Screen是最佳选择。完成后,您将在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。

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();
       }
    }
 }

在要显示的Model对象上将继承PropertyChangedBase

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

另一件需要注意的事情是项目中的IoC容器,实际上有2个。1 SimpleContainer 2 MEF,如果不是所有样本,则大多数样本都使用MEF。