我有一个WPF窗口左侧有任务列表,右侧有有关所选任务的详细信息。任务只是一个任务集合,你可以认为它是POCO。
具有任务和所选任务的单个ViewModel
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>
我的MainWindow xaml代码隐藏:
public partial class MainWindow : Window
{
private MainWindow()
{
DataContext = _tasksViewModel;
}
private void OnListBoxTasksSelectionChanged(object sender, SelectionChangedEventArgs e)
{
_tasksViewModel.CurrentTask = task;
DataContext = _tasksViewModel;
}
}
现在的问题是:
我应该拥有多少个视图模型?
在XAML中绑定以及在C#中设置数据上下文的最佳方法是什么?
如何为整个Window只有一个DataContext?如果Window的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;
}
答案 0 :(得分:2)
Binding中的路径可以深深地绑定到DataContext的属性中。级别用点分隔。您还可以从绑定中访问索引器。
如果您的DataContext是例如您通过说{Binding CurrentTask}
绑定到CurrentTask的TasksViewModel。此外,您通常会将 ListBox 的 SelectedItem 绑定到 CurrentTask 。
错误的是尝试从DependencyObject继承为ViewModel并指定依赖项属性。如果要指定绑定,则需要依赖项属性。 ViewModels只是数据源。
因此,正确的方法是通过引发属性更改的事件来实现 INotifyPropertyChanged 和notity WPF