我有一个 MVVM 项目,其 DataContext
中有一个 View 和一个 ViewModel .
在这个项目中,我有一个类 ComboBoxCustom
它继承自 ComboBox
。我在 ComboBoxCustom
中定义了一些附加功能类。
至此ComboBoxCustom
类我指定一个控件模板来定义其外观。
定义(简化)控件模板的(简化)样式如下所示:
<Style TargetType="{x:Type lib:ComboBoxCustom}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type lib:ComboBoxCustom}">
<StackPanel>
<TextBlock Text="{TemplateBinding TextPropertyInComboBoxCustom}"/>
<ComboBox DataContext="{TemplateBinding DataContext}"
ItemsSource="{TemplateBinding ItemsSource}"
DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
SelectedValuePath="{TemplateBinding SelectedValuePath}"
SelectedValue="{TemplateBinding SelectedValue}"
SelectedItem="{TemplateBinding SelectedItem}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
位于 ResourceDictionary
。真正的控制模板有一些附加功能,由于它们与问题无关,因此被省略。
我用这个ComboBoxCustom
在我的 View 中控制使用:
<lib:ComboBoxCustom ItemsSource="{Binding MyObservableCollectionOfMyObjects}"
TextPropertyInComboBoxCustom="MyText"
DisplayMemberPath="MyDescription"
SelectedValuePath="MyValue"
SelectedItem="{Binding SelectedMyObject, Mode=TwoWay}"/>
View 正常,所有项目都加载到我可以选择的组合框中。
问题是,当我在组合框中选择不同的项目时,属性 SelectedMyObject
我的 ViewModel 中没有更新,因此它的 setter 没有被调用。因此,有关所选对象的(正确)信息在我的 ViewModel 中不可用。
当我使用<ComboBox .../>
时(没有 TextPropertyInComboBoxCustom
属性)而不是 <lib:ComboBoxCustom .../>
一切工作正常,但我没有 ComboBoxMessage
中定义的附加功能我需要的。
任何人都可以告诉我出了什么问题以及如何解决此问题,以便我可以使用 ComboBoxMessage
在我看来?最好不破坏 MVVM 模式。
谢谢!
最佳答案
感谢 ASh 在 this post 中的评论和信息.
问题是 TemplateBinding
是一种方法。因此,来自 ViewModel 的所有信息都可以进入模板中的控件。但反之则不然。
解决方案是将普通绑定(bind)指定为:
SelectedItem ="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
它的功能与 TemplateBinding
大致相同,但有两种方式。
控件模板变成:
<Style TargetType="{x:Type lib:ComboBoxCustom}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type lib:ComboBoxCustom}">
<StackPanel>
<TextBlock Text="{TemplateBinding TextPropertyInComboBoxCustom}"/>
<ComboBox DataContext="{TemplateBinding DataContext}"
ItemsSource="{TemplateBinding ItemsSource}"
DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
SelectedValuePath="{TemplateBinding SelectedValuePath}"
SelectedValue="{TemplateBinding SelectedValue}"
SelectedItem ="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
但我不确定 SelectedValue
属性。对于这样的模板,当我使用 SelectedValue
属性或 SelectedItem
属性时,它都可以工作。
可以在 View 中省略 Mode=TwoWay
选项,因为 SelectedItem
的默认绑定(bind)模式已经是两种方式。 View 线变为:
<lib:ComboBoxCustom ItemsSource="{Binding MyObservableCollectionOfMyObjects}"
TextPropertyInComboBoxCustom="MyText"
DisplayMemberPath="MyDescription"
SelectedValuePath="MyValue"
SelectedItem="{Binding SelectedMyObject}"/>
关于c# - 从 ViewModel 到 Custom-Control 到 ControlTemplate 上的控件的多阶段绑定(bind)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42835295/