如何将ComboBox的ItemsSource与SelectedItem绑定到不同DataContext?
解决ComboBox跨两个独立数据源绑定的方案
方法1:用静态资源直接绑定
不用设置Page的DataContext,直接在XAML资源里声明两个对象的实例,绑定的时候指定对应资源:
<Page.Resources> <local:MaterialLibrary x:Key="MaterialLib"/> <local:UserInputData x:Key="UserInput"/> </Page.Resources> <ComboBox ItemsSource="{Binding Source={StaticResource MaterialLib}, Path=MaterialNames}" SelectedItem="{Binding Source={StaticResource UserInput}, Path=SelectedMaterialName, Mode=TwoWay}"/>
这种方式完全满足两个对象独立、不用互相引用的要求,直接绕开单一DataContext的限制。
方法2:包装成中间ViewModel
如果习惯用单一DataContext的模式,新建一个ViewModel类把两个对象包起来:
public class PageViewModel : INotifyPropertyChanged { public MaterialLibrary MaterialLib { get; } public UserInputData UserInput { get; } public PageViewModel(MaterialLibrary materialLib, UserInputData userInput) { MaterialLib = materialLib; UserInput = userInput; } // 实现INotifyPropertyChanged,后续如果要更新这两个属性的话需要,否则可以省略 public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
后台代码设置DataContext:
public YourPage() { InitializeComponent(); // 这里替换成你实际的两个对象实例 DataContext = new PageViewModel(YourMaterialLibInstance, YourUserInputInstance); }
XAML绑定写法:
<ComboBox ItemsSource="{Binding MaterialLib.MaterialNames}" SelectedItem="{Binding UserInput.SelectedMaterialName, Mode=TwoWay}"/>
这个方法既保持了两个对象的独立性,又符合单一DataContext的开发习惯。
方法3:通过元素引用绑定(适用于已有控件承载数据源的场景)
如果其中一个对象已经绑定到页面内的其他控件,可以用ElementName或者RelativeSource引用:
比如页面里有个ContentControl绑定了MaterialLibrary:
<ContentControl x:Name="MaterialHost" DataContext="{StaticResource MaterialLib}"/>
那ComboBox可以这么写:
<ComboBox ItemsSource="{Binding DataContext.MaterialNames, ElementName=MaterialHost}" SelectedItem="{Binding Source={StaticResource UserInput}, Path=SelectedMaterialName, Mode=TwoWay}"/>
适合已有控件承载了其中一个数据源的场景,灵活度高。
内容的提问来源于stack exchange,提问作者Justin8051
相关产品推荐
相关产品推荐

