指定要在运行时显示的多个WPF DataGrids之一

时间:2012-02-15 21:42:00

标签: c# wpf xaml binding user-controls

在我的应用程序中,我想要一个下拉框来选择要编辑的表(大约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的新手,所以我可能错过了一些明显的东西。谢谢!

2 个答案:

答案 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之间进行更改。

我很想知道为什么初始绑定是错误的。但是,我现在要求一个小小的胜利,并将这个难题留到另一天。