使ViewModel属性可用于绑定到IsChecked

时间:2014-03-14 10:51:17

标签: wpf mvvm binding caliburn.micro

我在我的应用中使用了Caliburn.Micro。我想做的是:

  • 在视图
  • 中为每个可用许可创建一个RadioButton
  • 检查当前有效许可证的人

到目前为止,我的ViewModel上有两个属性(我在这里省略INotify...Changed及其实现,因为它可以工作):

BindableCollection<LicenceInfo> AvailableLicences { get; set; }
LicenceInfo ActiveLicence { get; set; }

在ViewModel的构造函数中,我填充AvailableLicencesActiveLicence。到目前为止,非常好。

目前在视图中,我有一个ItemsControl,其中包含RadioButton和一个不可见的FrameworkElement,可以传递给MyConverter,我在其中提取{{1} {}}的DataContext和不可见的Self(其FrameworkElement绑定到ViewModel)并将它们与(重写)DataContext进行比较:

LicenceInfo.Equals()

这实际上是按预期工作的,但在我看来,这似乎是一个丑陋的解决方法,我确信我错过了一些东西。

使用<FrameworkElement Name="ActiveLicence" Visibility="Collapsed" /> <ItemsControl Name="AvailableLicences"> <ItemsControl.ItemTemplate> <DataTemplate> <RadioButton cal:Message.Attach="[Event Checked] = [Action ChangeActiveLicence($dataContext)]"> <RadioButton.IsChecked> <MultiBinding Converter="{StaticResource MyConverter}" Mode="OneWay"> <Binding RelativeSource="{RelativeSource Self}" /> <Binding ElementName="ActiveLicence" /> </MultiBinding> </RadioButton.IsChecked> [...] <Binding x:Name="ActiveLicence" />作为第二个参数并删除不可见的<Binding Path="ActiveLicence" />不起作用,ViewModel属性未附加到绑定。

我不一定要使用FrameworkElement。任何与处理MultiBinding事件的动作类似的Caliburn.Micro动作都会受到欢迎。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

从我的角度来看,如果在LicenceViewModel上添加一个标志不是一个选项,那么你在这里非常接近一个好的解决方案:

尝试以下多重绑定,而不是使用容器框架元素:

<MultiBinding Converter="{StaticResource MyConverter}" Mode="OneWay">
    <Binding Path="DataContext" RelativeSource="{RelativeSource Self}" />
    <Binding Path="DataContext.ActiveLicense" RelativeSource="{RelativeSource FindAncestor, AncestorType=ItemsControl}" />
</MultiBinding>

修改转换器以使用Equals()比较两个对象,与具体类型无关。这样,你就不会搞乱不必要的对象,仍然可以正确地分离 Views ViewModels

修改

关于带有标志的替代解决方案:我没有注意到,您的代码中没有涉及LicenseViewModel ...在许可证信息中添加标志不是一个好的解决方案,我同意。您可以考虑将LicenseInfo包装在LicenseInfoViewModel内,但这需要一些基础结构来进行模型上LicenseInfo的原始集合与包含该ViewModel的集合之间的同步。 ViewModel秒。

我已就该主题here发布了广泛的答案。

然后,当ActiveLicense属性发生更改时,您可以将活动许可证{{1}}的标志设置为true,将所有其他标志设置为false。

这是一个具体背景的问题,在这里加倍努力是否有意义。如果您不打算随着时间的推移扩展功能等,而且只是简单的许可证选择,第一种解决方案就足够了。