Considere un WPF DataGrid con DataGridTemplateColumn (s) y con el usuario iniciado agregando CanUserAddRows="True" permitido, por ejemplo

<DataGrid AutoGenerateColumns="False" CanUserAddRows="True" ItemsSource="{Binding Options}">
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <RadioButton IsChecked="{Binding IsChecked}" GroupName="OptionsRad"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTextColumn Header="Option" Binding="{Binding OptionName}"/>
    </DataGrid.Columns>
</DataGrid>

Se puede interactuar con RadioButton gracias a estar alojado con DataGridTemplateColumn sin ingresar CellEditingMode, que es lo esperado y deseado.
Sin embargo, existe el problema de que en el último, 'agregar nueva opción', tipo de fila, el RadioButton se puede interactuar con incluso antes de agregar una nueva opción (es decir, se se ingresa el nombre agregado). Posiblemente eligiendo una opción inexistente y moviendo el foco a otra parte.
radio
¿Cómo puedo deshabilitar la interacción con la columna de la plantilla antes de agregar una nueva fila a la colección enlazada?

0
wondra 16 oct. 2018 a las 14:01

2 respuestas

La mejor respuesta

Puede usar un convertidor para lograr lo que está tratando de hacer.

Supuse que tienes una clase o tipo de datos para representar tus datos de Option y Options es una colección de esos elementos.

Puede configurar IsEnabled en RadioButton para:

IsEnabled="{Binding Path=Item, RelativeSource={RelativeSource AncestorType=DataGridRow"}, Converter={StaticResource DataToEnabledConverter}}"

Y el código del convertidor se vería así:

public class DataToEnabledConverter : IValueConverter
{
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
     {
         return value is Option;
     }

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
     {
         throw new NotImplementedException();
     }
}

Tu XAML completa se vería así:

    <DataGrid AutoGenerateColumns="False" CanUserAddRows="True" ItemsSource="{Binding Options}">
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <RadioButton IsChecked="{Binding IsChecked}" GroupName="OptionsRad" 
                                     IsEnabled="{Binding Path=Item, RelativeSource={RelativeSource AncestorType=DataGridRow"}, Converter={StaticResource DataToEnabledConverter}}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Header="Option" Binding="{Binding OptionName}"/>
        </DataGrid.Columns>
    </DataGrid>

Esto funciona porque la propiedad Item en DataGridRow para filas nuevas sería de tipo NamedObject, no su tipo de datos.

0
Suresh 17 oct. 2018 a las 02:23

También puede comparar con NewItemPlaceholder únicamente en XAML:

<DataTemplate>
    <RadioButton x:Name="Radio" IsChecked="{Binding IsChecked}" GroupName="OptionsRad" />
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Item, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridRow}}"
                     Value="{x:Static CollectionView.NewItemPlaceholder}">
            <Setter TargetName="Radio" Property="IsEnabled" Value="False" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>
1
Miral 24 jul. 2019 a las 04:21