Fruchtzwerg
Fruchtzwerg

Reputation: 11389

How to disable a specific DataGid Cell of a new row

I have a simple DataGrid with two columns like

<DataGrid ItemsSource="{Binding Commands}" CanUserAddRows="True" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Value" Binding="{Binding Value}"/>
        <DataGridTemplateColumn Header="Command">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding ComboItems}" SelectedValue="{Binding SelectedItem}">
                        <ComboBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Converter={StaticResource ItemConverter}}"/>
                            </DataTemplate>
                        </ComboBox.ItemTemplate>
                    </ComboBox>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

My goal is to disable the cell with the ComboBox of the new row. The following picture shows my DataGrid (bound to a ObservableCollection of two items) with the column to disable marked.

enter image description here

I tried already to use a converter to disable the ComboBox

IsEnabled="{Binding Value, Converter={StaticResource DisableConverter}}"

but the converter don't get's called until I entered a value inside the first column.

Hope anybody can help me!

Upvotes: 2

Views: 531

Answers (2)

user6996876
user6996876

Reputation:

Based on this previous answer, you can achieve this in the Loaded event handler

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        var dataGridRow = FindChild(dataGrid, x =>
        {
            var element = x as DataGridRow;
            if (element != null && element.Item == System.Windows.Data.CollectionView.NewItemPlaceholder)
                return true;
            else
                return false;
        }) as DataGridRow;
        var combo = FindChild(dataGridRow, x =>
        {
            return x is ComboBox;
        }) as ComboBox;
        combo.IsEnabled = false;
    }

with this helper

    public static DependencyObject FindChild(DependencyObject parent, Func<DependencyObject, bool> predicate)
    {
        if (parent == null) return null;

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);

            if (predicate(child))
            {
                return child;
            }
            else
            {
                var foundChild = FindChild(child, predicate);
                if (foundChild != null)
                    return foundChild;
            }
        }

        return null;
    }

Upvotes: 1

mm8
mm8

Reputation: 169200

You could apply the following Style to the ComboBox:

<ComboBox ItemsSource="{Binding ComboItems}" SelectedValue="{Binding SelectedItem}">
    <ComboBox.Style>
        <Style TargetType="ComboBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=DataContext,RelativeSource={RelativeSource AncestorType=DataGridRow}}" 
                                                         Value="{x:Static CollectionView.NewItemPlaceholder}">
                    <Setter Property="IsEnabled" Value="False" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ComboBox.Style>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource ItemConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

Upvotes: 3

Related Questions