【发布时间】:2013-07-26 10:00:19
【问题描述】:
我正在构建一个 WPF 应用程序(.NET 4.0),我有以下情况:
<ListBox
ItemsSource="{Binding Path=Items}"
SelectedItem="{Binding Path=SelectedItem}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Height" Value="48"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<!-- ... -->
<CheckBox>
<CheckBox.IsChecked>
<!-- Something here that behaves like SelectedItem binding -->
</CheckBox.IsChecked>
</CheckBox>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
- ListBox 的 ItemSource 绑定到 ObservableCollection。
- ListBox 的 SelectedItem 绑定到 SelectedItem 属性 ViewModel 的。
但是,当 ViewModel.SelectedItem 更新时,会启动一些长时间运行(2-3 秒)的异步任务。 通过简单地选择列表框中的不同项目来排队大量异步任务太容易了,所以我正在研究将 ViewModel.SelectedItem 绑定到 CheckBox(包含在 ItemTemplate 中)。
我对 WPF 相当陌生,但在 Forms 中我会附加一个事件处理程序并编写一些长而丑陋的代码来取消检查除触发事件的项目之外的所有项目,然后以编程方式更新属性。
在 WPF 中,我希望有更好的解决方案,我已经研究过使用 ValueConverter,但我不知道如何绑定到父视图模型(具有 ObservableCollection)。
如果有人遇到类似的要求,我真的很感激一些指点。
干杯!
./弗雷德里克
【问题讨论】:
-
重复点击复选框让大量异步任务排队不是同样容易吗?我想您需要的是一种机制,可以在启动新任务时取消当前正在运行的任务。并且您可以考虑延迟启动任务,而不是在所选项目更改时立即执行。
-
嗨克莱门斯,感谢您的回复!是的,它会,但是在异步任务运行时防止更改检查状态应该不会太难。我通过在任务运行时禁用 ListBox 来尝试相同的方法,但这太难看了。添加 CheckBox 的好处是 ListBox 中的选择与任务分离,允许用户在任务运行时浏览列表框。
-
您还可以考虑在列表框之外有一个专用按钮(而不是所有复选框)来启动当前所选项目的任务。这不仅更容易实现,而且还可能带来更直观的 UI。
-
一个很好的建议,这是我目前正在使用的后备。不过,我更喜欢 Chckbox,因为选中状态提供了有关“我选择了什么”的信息。使用按钮,我必须添加标签或其他内容以指示单击按钮时选择了哪些项目。
标签: wpf mvvm listbox checkedlistbox