2011-09-02 98 views
0

我有一个WPF窗口,其任务列表在左侧,有关右侧选定任务的详细信息。任务只是一个任务的集合,你可以考虑它的POCO。绑定到DataContext的子类

单视图模型兼具任务和所选择的任务

public class TaskViewModel 
{ 
    public TaskViewModel() 
    { 
     Tasks = new Task().GetTasks(); 
    } 


    // A LIST OF MANY TASKS 
    private Tasks _tasksViewModel; 
    public Tasks Tasks 
    { 
     get { return _tasksViewModel; } 
     private set 
     { 
      _tasksViewModel= value; 
     } 
    } 


    // A SINGLE SELECTED TASK 
    private static readonly DependencyProperty CurrentTaskProperty = DependencyProperty.Register(
     "CurrentTask", typeof(Task), typeof(TaskViewModel), new PropertyMetadata(null)); 
    public Task CurrentTask 
    { 
     get { return (Task) GetValue(CurrentTaskProperty); } 
     set { SetValue(CurrentTaskProperty, value); } 
    } 
} 

窗口在XAML:

<Window> 
    <!-- A List with multiple tasks. --> 
    <ListBox x:Name="listBoxTasks" ItemsSource="{Binding Path=Task, Mode=TwoWay} /> 

    <!-- The List's selected task's "Task Name" property. --> 
    <TextBox x:Name="textBoxTaskName" Text="{Binding Path=CurrentTask, Mode=TwoWay}" />  

    <!-- The List's selected tasks' "Task Items" child objects. --> 
    <ListBox x:Name="listBoxTaskItems" ItemsSource="{Binding Path=EditableValue, Mode=TwoWay}" /> 
</Window> 

而我的主窗口的XAML代码隐藏:

public partial class MainWindow : Window 
{ 
    private MainWindow() 
    { 
     DataContext = _tasksViewModel; 
    } 

    private void OnListBoxTasksSelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     _tasksViewModel.CurrentTask = task; 
     DataContext = _tasksViewModel; 
    } 
} 

而现在的问题:

我应该有多少个视图模型有哪些?

  • 我应该添加第二个ViewModel吗?我是否应该有一个用于任务的ViewModel,另一个用于所选的任务,或者我应该只有一个ViewModel用于整个窗口?

什么是最好的方式来绑定在XAML,并在C#中设置数据上下文(S)?

  • 如何为整个窗口只有一个DataContext?如果窗口的DataContext是TasksViewModel,我该如何将某些东西绑定到TasksViewModel.CurrentTask?有没有办法绑定到Window.DataContext的子项的属性,或者是否需要为使用CurrentTask的任何控件手动指定单独的DataContext?

    • 有没有办法做到这一点是这样的:

在C#:

DataContext = _tasksViewModel.Tasks 

在XAML:

<!-- Can I do something similar to DataContext.CurrentTask.TaskName ??? --> 
<TextBox x:Name="textBoxTaskName" MinWidth="100" Text="{Binding Path=DataContext.CurrentTask.TaskName, Mode=TwoWay}" /> 

<!-- What about DataContext.CurrentTask.TaskItems??? --> 
<ListBox x:Name="listBoxTaskItems" ItemsSource="{Binding Path=**DataContext.CurrentTask.TaskItems**, DisplayMember="TaskItemName}" /> 

或者换句话说,有没有更好的解决方案,而不是这样做:

// When a Task in Tasks is selected... 
OnListBoxTasksSelectionChanged() 
{ 
    [...] 

    // Set that Task as the DataContext for other controls 
    textBoxTaskName.DataContext = Task; 

    listBoxTaskItems.DataContext = Task.TaskItems; 
} 

回答

2

在你的绑定可以深深绑定到DataContext的性能的路径。级别由点分隔。您还可以从绑定中访问索引器。

如果你的DataContext是例如TasksViewModel通过说{Binding CurrentTask}绑定到CurrentTask。此外,您通常会将您的列表框选定的项目复制到CurrentTask

试图从DependencyObject作为ViewModel继承并指定依赖项属性是明显错误的。需要指定绑定的依赖项属性。 ViewModels只是数据源。

因此,正确的做法是实施INotifyPropertyChanged的和notity通过提高其你的属性而改变

+0

这是绑定文本框中正确的语法事件WPF?当我的SelectedTask改变时,仍然无法显示它。 ' private Task _currentTask; public Task CurrentTask { get {return _currentTask; } set { _currentTask = value; OnPropertyChanged(“CurrentTask”); OnPropertyChanged(“CurrentTask.TaskName”); OnPropertyChanged(“TaskName”); ..' – Shawn

+0

绑定的默认参数是“路径”,所以基本上声明路径两次(CurrentTask,Key) - 尝试组合它们:Path = CurrentTask.Key – flq