2016-12-28 14 views
1

Я пытаюсь создать элемент управления DataGrid для управления сеткой свойств. У меня есть абстрактный класс для моего базового класса параметров, который реализуют параметры различных типов. Этот базовый класс содержит переменные, которые совместно используются для каждого параметра (например, Group, Name, IsLocked и т. Д.), А затем каждый параметр управляет информацией, относящейся к определенному типу. Например, параметр number может использовать ползунок для пользовательского элемента управления, который также затем использует значения min/max и т. Д.Проблема с DataBinding WPF: UserControls в ячейках DataGrid не привязаны

Я создал класс, который является наблюдаемой коллекцией моего базового параметра, и установил его как статический ресурс для 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. Моя другая колонка отлично работает, при этом каждое значение ключа отображается правильно и обновляется (для этого примера это только столбец «Ключ», но все поля из базового класса ведут себя отлично.) Правильные UserControl также выбираются на основе на UIType DataTrigger, но UserControls просто создают экземпляр из пустого конструктора и не связывают его.

Я также подтвердил, что автономные экземпляры моих UserControls работают нормально и корректно связывают. Для, например, она работает, когда я устанавливаю DataContext из кода позади (который я не хочу делать):

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

Я также попытался удалить DataContext = «{Binding}» из моих пользовательских элементов управления , но это ничего не меняет.

ответ

0

Если вы хотите поместить различные элементы управления для различных подклассов, задавать различные DataTemplates, а затем

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

Это очень упростило мой XAML (спасибо!), однако во время выполнения я получаю такое же поведение, что в моем DataGrid появляется правильный usercontrol, но его DataContext не связан. – davestasiuk

+0

Я нашел решение, выполнив DependencyProperty для каждого моего подкласса UserControls. См. Ответ ниже. – davestasiuk

1

В связи с предложением механика выше, что значительно упростило XAML для моей собственности сетки, в ходе дальнейших исследований я узнал, что мне нужно реализовать DependencyProperty для каждого подзадачного пользовательского контроля. Где я установил DataTemplate для каждого типа данных в моей сетке свойств UserControl, я установил привязку к моему 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>

Затем в коде позади моих UserControls, я реализовать 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(); 
} 

Наконец, в каждом UserControl, я убедиться, что я дал ему имя, и затем установите привязку к правильной переменной в моем 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>

Я надеюсь, что это помогает кто-то другой!

 Смежные вопросы

  • Нет связанных вопросов^_^