2012-02-15 36 views
1

在我的應用程序中,我想要一個下拉框來選擇要編輯的表格(約20個)。每個表都應該由其自己的WPF DataGrid表示。 (我想過使用單個DataGrid並在運行時創建一組新的列,並使用代碼隱藏功能,但這看起來不太符合XAML-ish。)指定要在運行時顯示的幾個WPF DataGrid中的一個

我的下拉列表位於UserControl中它是更大的應用程序的一部分)。我相信(從我的研究),對單的-20的DataGrid中的佔位符應作爲一個佔位符這裏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(); 
    } 
} 

而且視圖模型(類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 x:Class="Choice1Control" 
      xmlns:my="clr-namespace:MyNamespace"> 
    <DataGrid ItemsSource="{Binding Choice1Objects}" /> 
     <!-- ... --> 
    </DataGrid> 
</UserControl> 

當用戶改變下拉我想程序加載適當的數據網格。現在我看不到子UserControl(在這裏,Choice1Control)。我直接添加了孩子(沒有介入的ContentControl),並且它工作正常。

我已經嘗試過幾乎所有DataContext和UserControl內容綁定的組合。我對WPF很陌生,所以我可能錯過了一些顯而易見的東西。謝謝!

+0

你在哪裏指定你的代碼中的數據源,即ViewSource ..等等......? – MethodMan 2012-02-15 21:53:31

+0

你是什麼意思?我的印象是將DataContext設置爲類「ViewModel」,並將ContentControl的內容設置爲指向「CurrentView」就足以指示控件的指定位置。你可以說得更詳細點嗎? – Tenner 2012-02-15 22:04:06

+0

我在Binding方面講的比較多..我看到你使用的是{Binding},但是Binding需要某種源 – MethodMan 2012-02-15 22:05:37

回答

0

由於某種原因,我從來沒有想到會在運行時在日誌中清晰地寫入綁定錯誤。我開始討論,直到我真正得到了有用的信息,並且可以找到問題的根源。

看來,根用戶控件的DataContext在被ContentControl繼承之前被攔截。 (或者,我對繼承/傳播DataContext的印象是錯誤的。)

最後,我更改了MyClass構造函數以明確指定DataContext作爲ViewModel

public MyClass() { 
    InitializeComponent(); 
    ViewModel = new MyViewModel(); 
    ViewModel.CurrentView = new DataGridChoice1();    
    this.DataContext = ViewModel;      // <-- Added this line 
} 

綁定然後按預期工作,我能爲下拉框中選擇多個DataGrid中之間的變化而變化的狀態。

我很想聽聽爲什麼初始綁定是錯誤的。不過,我現在要宣告一個小小的勝利,並且將在這一天留下這個難題。

1

Path需要一個Source來抵擋(Source,DataContext,RelativeSource,ElementName)。 ElementName只能用於引用XAML中用x:Name聲明的元素。

+0

沒有指定Binding RelativeSource有效地覆蓋DataContext?我做了什麼錯誤:將DataContext指定爲附加的ViewModel?我對你的例子的印象是它將使用父窗口的DataContext,它是我的應用程序的最高級別,並且將具有不同於此處使用的DataContext。爲了好玩,我也嘗試過使用'{Binding RelativeSource = {RelativeSource Mode = FindAncestor,AncestorType = {x:Type UserControl}},Path = CurrentView}',但結果相同。 :-( – Tenner 2012-02-15 22:18:33

+0

,如果你試試這個 MethodMan 2012-02-15 22:22:51

+0

這不是問題,作爲一個測試我替換了我的''with''並且Choice1Control如預期的那樣出現DataGrid的DataContext和Binding本身是好吧,它是DataContext/Binding將子DataGrid附加到UserControl的行爲不當(感謝您持續的幫助,順便說一句) – Tenner 2012-02-15 22:29:11

相關問題