如何将按钮内ComboBox的SelectedItem作为Button的CommandParameter传递?
搞定按钮内部ComboBox的CommandParameter绑定问题
嘿,你遇到的这个问题其实是WPF模板的命名作用域隔离导致的,我之前也踩过这个坑!
为啥原来的绑定失效?
ContentTemplate是个独立的可视化树模板,里面的AssetClassInButton属于模板自己的命名空间,外部的SimpleButton根本看不到它——用ElementName去查找模板内的控件,就像在别人家找自己家的东西,肯定找不到啊!
两种解决方案任你选
方案1:快速修复(适合不想改ViewModel的情况)
用RelativeSource配合模板的FindName方法,直接从按钮的ContentTemplate里找到ComboBox:
<dx:SimpleButton Margin="0,5,0,5" MinWidth="160" Command="{Binding CreateNewSymbolCommand}" CommandParameter="{Binding Path=ContentTemplate.FindName('AssetClassInButton', this).SelectedItem, RelativeSource={RelativeSource Self}}"> <dx:SimpleButton.ContentTemplate> <DataTemplate> <StackPanel Orientation="Vertical"> <TextBox Text="Choose Asset Class" Foreground="LightGreen" HorizontalAlignment="Center"/> <dxe:ComboBoxEdit Name="AssetClassInButton" MinWidth="150" IsTextEditable="False" ItemsSource="{Binding Source={StaticResource AssetClassEnumValues}}"/> </StackPanel> </DataTemplate> </dx:SimpleButton.ContentTemplate> </dx:SimpleButton>
不过这种方式依赖模板内控件的命名,后续改模板名字容易出问题,更推荐下面的MVVM规范方案。
方案2:符合MVVM思想的长期方案(更推荐)
既然用了MVVMLight,不如把选中项绑定到ViewModel的属性上,这样不仅CommandParameter能拿到值,后续业务逻辑也能直接用这个属性:
- ViewModel里加属性和命令:
// 假设你的枚举类型是AssetClassEnum private AssetClassEnum _selectedAssetClass; public AssetClassEnum SelectedAssetClass { get => _selectedAssetClass; set => Set(ref _selectedAssetClass, value); // MVVMLight的Set自动触发属性变更通知 } // 你的ICommand<T> public ICommand<AssetClassEnum> CreateNewSymbolCommand { get; } // 构造函数初始化命令 public YourViewModel() { CreateNewSymbolCommand = new RelayCommand<AssetClassEnum>(selectedClass => { // 这里直接用selectedClass参数,或者用SelectedAssetClass属性都可以 HandleCreateNewSymbol(selectedClass); }); }
- 修改XAML绑定:
<dx:SimpleButton Margin="0,5,0,5" MinWidth="160" Command="{Binding CreateNewSymbolCommand}" CommandParameter="{Binding SelectedAssetClass}"> <dx:SimpleButton.ContentTemplate> <DataTemplate> <StackPanel Orientation="Vertical"> <TextBox Text="Choose Asset Class" Foreground="LightGreen" HorizontalAlignment="Center"/> <dxe:ComboBoxEdit MinWidth="150" IsTextEditable="False" ItemsSource="{Binding Source={StaticResource AssetClassEnumValues}}" SelectedItem="{Binding DataContext.SelectedAssetClass, RelativeSource={RelativeSource AncestorType=dx:SimpleButton}}"/> </StackPanel> </DataTemplate> </dx:SimpleButton.ContentTemplate> </dx:SimpleButton>
这里ComboBox的SelectedItem通过RelativeSource找到外部的SimpleButton,再绑定到它的DataContext(也就是你的ViewModel)的SelectedAssetClass属性。按钮的CommandParameter直接绑定这个ViewModel属性,完美避开模板命名空间的问题,还符合MVVM的分离原则。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

