【发布时间】:2011-09-02 22:11:11
【问题描述】:
我有一个 WPF 窗口,左侧有一个任务列表,右侧有所选任务的详细信息。 tasks只是task的集合,可以考虑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;
}
}
现在是问题:
我应该有多少个视图模型?
- 我应该添加第二个 ViewModel 吗?我应该有一个 ViewModel 用于 Tasks,一个 ViewModel 用于选定的 Task,还是应该只有一个 ViewModel 用于整个窗口?
在 XAML 中绑定以及在 C# 中设置数据上下文的最佳方式是什么?
-
我怎样才能让整个窗口只有一个 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;
}
【问题讨论】:
标签: c# wpf xaml data-binding binding