简体   繁体   中英

InvalidOperationException in WPF form when trying to change cell color in DataGrid

I cannot say that I am new to WPF, because it would be too much. I just was given with WPF app to maintain...

I need to change particular cell color in DataGrid based on a value. I thought it would be easy, found that SO post: Change DataGrid cell colour based on values .

Pasted where it belongs, which gave me the following:

<DataGrid x:Name="DgDevices" ItemsSource="{Binding}" BorderThickness="2,0,2,2" Cursor="Cross">
    <DataGrid.ContextMenu>
        <ContextMenu >
            <MenuItem Header="Załóż Deblokadę" Click="InsertDBL"  />
            <MenuItem Header="Usuń Deblokadę" Click="RemoveDBL"/>
        </ContextMenu>
    </DataGrid.ContextMenu>
    <DataGridTextColumn Binding="{Binding Name}">
        <DataGridTextColumn.ElementStyle>
            <Style TargetType="{x:Type TextBlock}">
                <Style.Triggers>
                    <Trigger Property="Text" Value="1">
                        <Setter Property="Background" Value="Black"/>
                        <Setter Property="Foreground" Value="White"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </DataGridTextColumn.ElementStyle>
    </DataGridTextColumn>
</DataGrid>

Now, when invoking Show method on this form, it gives me InvalidOperationException . I searched for explanation why this happens, but haven't found clear explanation.

Also, I know that Binding Name is placeholder for my binding (in <DataGridTextColumn Binding="{Binding Name}"> ), so I tired putting just Binding there (inspired by ItemsSource="{Binding}" in DataGrid node), but didn't solve the issue.

You are now adding DataGridTextColumn right into DataGrid itself, not to its columns list. Adding items directly and using ItemsSource are mutually exclusive, so InvalidOperationException is thrown (and you didn't intend to add column as item anyway). Instead, do it like this:

<DataGrid x:Name="DgDevices"
          ItemsSource="{Binding}"
          BorderThickness="2,0,2,2"
          AutoGenerateColumns="False"
          Cursor="Cross">
    <DataGrid.ContextMenu>
        <ContextMenu >
            <MenuItem Header="Załóż Deblokadę" Click="InsertDBL"  />
            <MenuItem Header="Usuń Deblokadę" Click="RemoveDBL"/>
        </ContextMenu>
    </DataGrid.ContextMenu>
    <DataGrid.Columns> <!-- add to columns -->
        <DataGridTextColumn Binding="{Binding Name}">
            <DataGridTextColumn.ElementStyle>
                <Style TargetType="{x:Type TextBlock}">
                    <Style.Triggers>
                        <Trigger Property="Text"
                                 Value="1">
                            <Setter Property="Background"
                                    Value="Black" />
                            <Setter Property="Foreground"
                                    Value="White" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGridTextColumn.ElementStyle>
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

Also, because you need to set AutoGenerateColumns to False , because otherwise DataGrid will automatically generate columns from your data source, in addition to columns you define manually, and you rarely need that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM