Стиль DataGridTemplateColumn для соответствия DataGridComboBoxColumn

РЕДАКТИРОВАТЬ (уточнение требований)

У меня DataGrid, как показано ниже. Значения в столбце «Имя поля для хранения старого EmpNo» изменяются в зависимости от значения, выбранного в столбце «Новое правило EmpNo». Для этого каждый элемент в DataGrid ItemsSource имеет свой собственный TableNameForOldDataCollection. Мне нужно привязаться к этому TableNameForOldDataCollection, а не к статическому свойству, которое нельзя изменить.

Если есть способ сделать эту привязку при использовании DataGridComboBoxTemplate, я бы предпочел это. Если нет, я хотел бы знать, можно ли создать шаблон _7 _ / _ 8_, чтобы он соответствовал шаблону DataGridComboBoxTemplate

OP

У меня есть сценарий, в котором я использую DataGridComboBoxColumn для одного из DataGrid столбцов. В другом столбце мне нужно использовать DataGridTemplateColumn с ComboBox, чтобы правильно привязать к динамическому ItemSource в виртуальной машине.

DataGridComboBoxColumn («Новое правило EmpNo») оформлено иначе, чем DataGridTemplateColumn, с ComboBox («Имя поля для хранения старого EmpNo»), как показано здесь:

введите описание изображения здесь

Как я могу стилизовать _17 _ / _ 18_, чтобы соответствовать DataGridComboBoxColumn, в частности, как скрывается поле со списком, когда фактическая ячейка не выбрана (например, вторая строка «Новое правило EmpNo»).

ИЗМЕНИТЬ (добавлен DataGrid код):

   <UserControl.Resources>
        <ResourceDictionary>
             <CollectionViewSource x:Key="StaticEmpNoRuleCollection" Source="{Binding EmpNoRuleCollection}" />                
        </ResourceDictionary>        
    </UserControl.Resources>

....

                <DataGrid Name="DataGrid_MultiCompanyInfo"
                          ItemsSource="{Binding Model.EmpNoOptionsCollection}"
                          SelectedItem="{Binding SelectedEmpNoOptions}"
                          AutoGenerateColumns="False"
                          CanUserAddRows="False"
                          CanUserDeleteRows="False">
                    <DataGrid.Columns>

                        <!-- Company -->
                        <DataGridTextColumn Header="Company" 
                                            Binding="{Binding Company}"
                                            IsReadOnly="True" />

                        <!-- New EmpNo Rule -->
                        <DataGridComboBoxColumn Header="New EmpNo Rule"
                                                Width="200"
                                                ItemsSource="{Binding Source={StaticResource StaticEmpNoRuleCollection}}"
                                                DisplayMemberPath="Description"
                                                SelectedValueBinding="{Binding SelectedEmpNoRule, UpdateSourceTrigger=PropertyChanged}"/>

                        <!-- Field Name To Store Old EmpNo -->
                        <DataGridTemplateColumn Header="Field Name To&#x0a;Store Old EmpNo"
                                                Width="150" >
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox Name="OldEmpNo_ComboBox"
                                              Margin="-5,0,0,0"
                                              ItemsSource="{Binding TableNameForOldDataCollection}"
                                              SelectedValue="{Binding TableNameForOldData, UpdateSourceTrigger=PropertyChanged}" />
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>

                        ...

                    </DataGrid.Columns>
                </DataGrid>

person BrianKE    schedule 20.09.2016    source источник
comment
Не могли бы вы опубликовать свой код DataGridTemplateColumn?   -  person Jose    schedule 20.09.2016
comment
@Kirenenko См. Правку в OP.   -  person BrianKE    schedule 20.09.2016
comment
Я думаю, что правильный путь - использовать DataGridComboBoxColumn в старом EmpNo, но вы должны правильно выполнить привязку, используя RelativeSource="{RelativeSource AncestorType={x:Type DataGrid}}".   -  person Jose    schedule 20.09.2016
comment
@Kirenenko Изначально я пошел по этому маршруту, который не сработал. Согласно ряду различных статей, которые я нашел, вы не можете делать то, что предлагаете, потому что DataGridComboBoxColumn не является частью визуального дерева (stackoverflow.com/questions/3659970/). Вот почему я должен использовать DataGridTemplateColumn. Выбираемые значения этого конкретного столбца изменяются в зависимости от выбранного значения другого столбца.   -  person BrianKE    schedule 20.09.2016
comment
Возможный дубликат Как привязать данные к DataGridComboBoxColumn в DataGrid с помощью MVVM   -  person Jose    schedule 22.09.2016


Ответы (1)


Помня, что DataGridComboBoxColumn находится не в том же визуальном дереве, вы можете использовать BindingProxy:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

Ресурсы XAML:

<Window.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</Window.Resources>

Привязка XAML (не в визуальном дереве):

<DataGridComboBoxColumn ItemsSource="{Binding Data.TableNameForOldDataCollection, Source={StaticResource proxy}}"/>

ОБНОВЛЕНИЕ

Совершенно другое решение ... Выглядит немного хакерским, но я протестировал его, и оно работает:

<DataGridComboBoxColumn Header="Field Name To&#x0a;Store Old EmpNo" Width="150"
SelectedItemBinding="{Binding TableNameForOldData, UpdateSourceTrigger=PropertyChanged}>
    <DataGridComboBoxColumn.ElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding TableNameForOldDataCollection}"/>
            <Setter Property="IsReadOnly" Value="True"/>
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style TargetType="ComboBox">
            <Setter Property="ItemsSource" Value="{Binding TableNameForOldDataCollection}"/>
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>

Также я думаю, что это дубликат, поэтому я отмечу его.

person Jose    schedule 20.09.2016
comment
Хотя мне нравится этот вариант предоставления привязываемой коллекции, он не работает для моего сценария (см. Дополнительные требования в OP). Похоже, что он привязан к коллекции в самом DataGrid, а не к свойству в каждом из элементов в EmpNoOptionsCollection. Если мне что-то не хватает, и это сработает, чтобы выполнить требования, не могли бы вы объяснить дальше? - person BrianKE; 20.09.2016
comment
Я думал, что ваш TableNameForOldDataCollection находится в вашем основном DataContext / ViewModel. Просто скажите мне, где объект для привязки, потому что вы должны указать на него данные прокси. - person Jose; 21.09.2016
comment
TableNameForOldDataCollection находится на каждом отдельном элементе в Model.EmpNoOptionsCollection. Каждый элемент в DataGrid имеет свою собственную копию TableNameForOldDataCollection, потому что значения могут изменяться в зависимости от значения StaticEmpNoRuleCollection - person BrianKE; 21.09.2016
comment
Вау ... Теперь я понял ... Это какая-то ItemsourceBindIngCeption. Позвольте проверить, могу ли я что-то сделать, но не уверен ... - person Jose; 21.09.2016