2016-12-28 38 views
1

我想構建一個DataGrid控件來管理屬性網格。我有一個抽象類,用於實現各種類型參數的參數基類。此基類包含在每個參數(如Group,Name,IsLocked等)之間共享的變量,然後每個參數管理與特定類型相關的信息。例如,一個數字參數可能會使用用戶控件的滑塊,然後使用最小/最大值等。WPF DataBinding問題:DataGrid單元格中的用戶控件未綁定

我已經建立了一個類,它是我的基本參數的Observable集合,並將其建立爲爲CollectionViewSource靜態資源:

<UserControl.Resources> 
    <local:Parameters x:Key="Parameters"/> 
    <CollectionViewSource x:Key="cvsParameters" Source="{StaticResource Parameters}" /> 
</UserControl.Resources> 

然後在我的DataGrid中,我使用風格引發了我的每一個參數的用戶控件之間切換:

<DataGrid x:Name="DataGrid_Globals" 
      ItemsSource="{Binding Source={StaticResource cvsParameters}}" 
      AutoGenerateColumns="False" 
      CanUserAddRows="False"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Key" Binding="{Binding Key}" IsReadOnly="True"/> 
     <DataGridTemplateColumn Width="*" > 
      <DataGridTemplateColumn.CellTemplate> 
       <DataTemplate> 
        <ContentControl> 
         <ContentControl.Style> 
          <Style TargetType="ContentControl"> 
           <Style.Triggers> 
            <DataTrigger Binding="{Binding UIType}" Value="Text"> 
             <Setter Property="ContentTemplate"> 
              <Setter.Value> 
               <DataTemplate> 
                <controls:ucText DataContext="{Binding}"/> 
               </DataTemplate> 
              </Setter.Value> 
             </Setter> 
            </DataTrigger> 
            <DataTrigger Binding="{Binding UIType}" Value="Number"> 
             <Setter Property="ContentTemplate"> 
              <Setter.Value> 
               <DataTemplate> 
                <controls:ucNumber DataContext="{Binding}"/> 
               </DataTemplate> 
              </Setter.Value> 
             </Setter> 
            </DataTrigger> 
           </Style.Triggers> 
          </Style> 
         </ContentControl.Style> 
        </ContentControl> 
       </DataTemplate> 
      </DataGridTemplateColumn.CellTemplate> 
     </DataGridTemplateColumn> 
    </DataGrid.Columns> 
</DataGrid> 

我的用戶控件都設置了自己的在XAML中聲明的數據上下文:

<UserControl.DataContext> 
    <local:TestNumber_cls/> 
</UserControl.DataContext> 
<Grid HorizontalAlignment="Stretch"> 
    <Slider 
     Value="{Binding NumberValue}" 
     Minimum="{Binding Min}" 
     Maximum="{Binding Max}" 
     /> 
</Grid> 

我想不出如何確保我的usercontrols正確綁定。我的其他列工作正常,每個Key值都顯示出來,被正確地綁定和更新(對於這個例子,它只是「Key」列,但是基類中的所有字段都表現得很好)。正確的UserControl也被選擇在UIType DataTrigger上,但UserControls只是從一個空的構造函數實例化並且不綁定。

我也確認了我的UserControls的獨立實例正常工作並正確綁定。因爲,例如,它的工作原理,當我從設定的代碼背後的DataContext(我不想做):

this.OneOffNumberUserControl.DataContext = ((Parameters)this.ParameterGrid.Resources["Parameters"])[2]; 

我還試圖刪除的DataContext =從我的用戶控件「{結合}」 ,但這並沒有改變任何東西。

回答

0

如果你想提出不同的子類不同的控制,指定不同的DataTemplates,然後

<!-- subtype-specific column --> 
          <DataGridTemplateColumn Header=""> 
           <DataGridTemplateColumn.CellTemplate> 
            <DataTemplate> 
             <ContentPresenter Content="{Binding}" /> 
            </DataTemplate> 
           </DataGridTemplateColumn.CellTemplate> 
          </DataGridTemplateColumn> 
+0

這非常簡化我的XAML(謝謝!),但是我在運行時得到相同的行爲,因爲正確的usercontrol出現在我的DataGrid中,但它的DataContext沒有綁定。 – davestasiuk

+0

我通過爲每個子類UserControls實現一個DependencyProperty來找到解決方案。見下面的答案。 – davestasiuk

1

與上述機械的建議,從而大大簡化了XAML爲我的屬性網格相結合,通過進一步的研究,我也瞭解到我需要爲每個依賴於子類的用戶控件實現一個DependencyProperty。在我的屬性網格UserControl中爲每個DataType設置DataTemplate的位置,我將綁定設置爲我的DependencyProperty。

<UserControl.Resources> 
 
    <local:Parameters x:Key="Parameters"/> 
 
    <CollectionViewSource x:Key="cvsParameters" Source="{StaticResource Parameters}" /> 
 
    <DataTemplate DataType="{x:Type local:TestText_cls}"> 
 
     <controls:ucText TextObject="{Binding}"/> 
 
    </DataTemplate> 
 
    <DataTemplate DataType="{x:Type local:TestNumber_cls}"> 
 
     <controls:ucNumber NumberObject="{Binding}"/> 
 
    </DataTemplate> 
 
</UserControl.Resources> 
 
<Grid> 
 
    <DataGrid x:Name="DataGrid_Globals" 
 
       ItemsSource="{Binding Source={StaticResource cvsParameters}}" 
 
       AutoGenerateColumns="False" 
 
       CanUserAddRows="False"> 
 
     <DataGrid.Columns> 
 
      <DataGridTextColumn Header="Key" Binding="{Binding Key}" IsReadOnly="True"/> 
 
      <DataGridTemplateColumn Width="*" > 
 
       <DataGridTemplateColumn.CellTemplate> 
 
        <DataTemplate> 
 
         <ContentPresenter Content="{Binding}"/> 
 
        </DataTemplate> 
 
       </DataGridTemplateColumn.CellTemplate> 
 
      </DataGridTemplateColumn> 
 
     </DataGrid.Columns> 
 
    </DataGrid> 
 
</Grid>

然後在我的用戶控件後面的代碼,我實現的DependencyProperty:

public static readonly DependencyProperty TextObjectProperty = 
    DependencyProperty.Register("TextObject", 
     typeof(TestText_cls), 
     typeof(ucText), 
     new PropertyMetadata(new TestText_cls())); 

[Bindable(true)] 
public TestText_cls TextObject 
{ 
    get { return (TestText_cls)this.GetValue(TextObjectProperty); } 
    set { this.SetValue(TextObjectProperty, value); } 
} 

public ucText() 
{ 
    InitializeComponent(); 
} 

最後,每個用戶控件中,我保證,我已經給了它一個名稱,然後在我的DependencyProperty中將我的綁定設置爲正確的變量:

<UserControl x:Class="Testing.ucText" 
 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 
      xmlns:local="clr-namespace:Testing.Classes" 
 
      mc:Ignorable="d" 
 
      d:DesignHeight="300" d:DesignWidth="300" 
 
      Name="TextUI"> 
 
    <Grid HorizontalAlignment="Stretch"> 
 
     <TextBox Text="{Binding ElementName=TextUI, Path=TextObject.Value}"/> 
 
    </Grid> 
 
</UserControl>

我希望這可以幫助其他人!