在我的应用程序中,我想要一个下拉框来选择要编辑的表(大约20个)。每个表都应该由自己的WPF DataGrid表示。 (我想过使用单个DataGrid并在运行时使用代码隐藏创建一组新列,但这似乎不是XAML-ish。)
我的下拉列表位于UserControl中(因为它是较大应用程序的一部分)。我相信(根据我的研究),20个DataGrids中的一个的占位符应该是一个ContentControl,用作占位符:
<UserControl x:Class="MyClass" ...
xmlns:my="clr-namespace:MyNamespace"
DataContext="{Binding ViewModel}">
<StackPanel>
<Grid>
<ComboBox Name="DataPaneComboBox" HorizontalAlignment="Stretch"
IsReadOnly="True" MinWidth="120"
Focusable="False" SelectedIndex="0"
DockPanel.Dock="Left" Grid.Column="0"
SelectionChanged="DataPaneComboBox_SelectionChanged">
<ComboBoxItem Name="FirstOption" Content="Choice 1" />
<ComboBoxItem Name="SecondOption" Content="Choice 2" />
<ComboBoxItem Name="ThirdOption" Content="Choice 3" />
</ComboBox>
</Grid>
<ContentControl Name="DataGridView" Margin="0,3,0,3" Content="{Binding CurrentView}" />
</StackPanel>
以下是此课程的代码隐藏:
public partial class MyClass : UserControl {
private MyViewModel ViewModel {
get; set;
}
public MyClass() {
InitializeComponent();
ViewModel = new MyViewModel();
ViewModel.CurrentView = new DataGridChoice1();
}
}
ViewModel(ObservableObject类实现了INotifyPropertyChanged接口):
public class MyViewModel : ObservableObject {
private UserControl _currentView;
public UserControl CurrentView {
get {
if (this._currentView == null) {
this._currentView = new DatGridChoice1();
}
return this._currentView;
}
set {
this._currentView = value;
RaisePropertyChanged("CurrentView");
}
}
#endregion
}
可以在运行时替换的20个左右的UserControl之一:
<UserControl x:Class="Choice1Control"
xmlns:my="clr-namespace:MyNamespace">
<DataGrid ItemsSource="{Binding Choice1Objects}" />
<!-- ... -->
</DataGrid>
</UserControl>
当用户更改下拉列表时,我希望程序加载适当的DataGrid。现在我看不到子UserControl(这里,Choice1Control
)。我直接添加了孩子(没有介入的ContentControl),它工作正常。
我已经尝试了DataContext和UserControl内容绑定的每个组合。我是WPF的新手,所以我可能错过了一些明显的东西。谢谢!
答案 0 :(得分:1)
Path需要一个Source来反对(Source,DataContext,RelativeSource,ElementName)。 ElementName只能用于通过x:Name引用在XAML中声明的元素。
答案 1 :(得分:0)
由于某种原因,我从未想过在运行时会在日志中清楚地写出Binding错误。我到处都是,直到我真正得到了一个有用的信息,并且可以找到问题的根源。
似乎根UserControl的DataContext在ContentControl可以继承之前被截获。 (或者,我对DataContext如何继承/传播的印象是错误的。)
最后,我更改了MyClass
构造函数,以将DataContext显式指定为ViewModel
。
public MyClass() {
InitializeComponent();
ViewModel = new MyViewModel();
ViewModel.CurrentView = new DataGridChoice1();
this.DataContext = ViewModel; // <-- Added this line
}
然后绑定按预期工作,并且当下拉框改变状态时,我能够在多个DataGrids之间进行更改。
我很想知道为什么初始绑定是错误的。但是,我现在要求一个小小的胜利,并将这个难题留到另一天。