M
M
Mikhail Usotsky2018-10-29 14:42:31
WPF
Mikhail Usotsky, 2018-10-29 14:42:31

How to handle an event from the DataTemplate of radio button clicks?

This DataTemplate is in the ListBoxItem via the ContentTemplate.

<DataTemplate x:Key="SelectContext">
        <Border x:Name="Data">
            <Grid x:Name="ContentBase"
                  Margin="1,0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Label Name="DisplayText"
                       Grid.Column="0"
                       Margin="0"
                       Padding="0"
                       HorizontalAlignment="Left"
                       Content="{Binding Content, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentPresenter}}"
                       Foreground="{Binding Foreground, RelativeSource={RelativeSource Mode=Self}}"/>
                <RadioButton Name="_1"
                             Grid.Column="1"
                             Content="1"
                             IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}"
                             Style="{StaticResource RadioButtonKeys}"/>
                <RadioButton Name="_2"
                             Grid.Column="2"
                             Content="2"
                             IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}"
                             Style="{StaticResource RadioButtonKeys}"/>
                <RadioButton Name="_3"
                             Grid.Column="3"
                             Content="3"
                             IsEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}"
                             Style="{StaticResource RadioButtonKeys}"/>
            </Grid>
        </Border>
    </DataTemplate>

Any idea how to pass radio button click event to code? I tried to attach a method to them through initialization in the code. Does not work. Tried to transfer through DataContext. Doesn't work either.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Alexey Pavlov, 2018-10-29
@AquariusStar

The ListBox (like the other ItemsControl descendant) has a list of items (it's most convenient to specify it via the ItemsSource). Each element of the list is built as a separate item. Each item is automatically set DataContext - the element of the source list that is being built. In the DataTemplate, it is good and correct to indicate the desired type that the element will have in the data context, then a hint will appear at the {Binding} inside the template.

public class Item : BaseViewModel
{
    private string _name;
    public string Name 
    { 
        get => _name;
        set
        {
            _name = value;
            RaisePropertyChanged();
        }
    }
    
    private int _itemMode;
    public int ItemMode 
    { 
        get => _itemMode;
        set
        {
            _itemMode = value;
            RaisePropertyChanged();
        }
    }
}

public class ItemsList
{
    public ObservableCollection<Item> Items { get; } = new ObservableCollection<Item>
    {
        new Item { Name = "Один", ItemMode = 1 },
        new Item { Name = "Два", ItemMode = 2 },
        new Item { Name = "Три", ItemMode = 3 },
    };
}

<Grid>
    <Grid.Resources>
        <converters:IntToBoolConverter x:Key="IntToBoolConverter"/>
        <DataTemplate DataType="{x:Type viewModels:Item}">
            <Border x:Name="Data">
                <Grid x:Name="ContentBase" Margin="1,0">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Label Name="DisplayText" Grid.Column="0" Content="{Binding Name}"/>
                    <RadioButton Name="_1" Grid.Column="1" Content="1" 
                                 IsChecked="{Binding ItemMode, Converter={StaticResource IntToBoolConverter}, ConverterParameter=1}"/>
                    <RadioButton Name="_2" Grid.Column="2" Content="2" 
                                 IsChecked="{Binding ItemMode, Converter={StaticResource IntToBoolConverter}, ConverterParameter=2}"/>
                    <RadioButton Name="_3" Grid.Column="3" Content="3" 
                                 IsChecked="{Binding ItemMode, Converter={StaticResource IntToBoolConverter}, ConverterParameter=3}"/>
                </Grid>
            </Border>
        </DataTemplate>
    </Grid.Resources>        
    <Grid.DataContext>
        <viewModels:ItemsList/>
    </Grid.DataContext>
    <ListBox ItemsSource="{Binding Items}"/>
</Grid>

BaseViewModel class code
public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Converter code
public class IntToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value != null 
            && parameter != null 
            && value.ToString() == parameter.ToString();
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || parameter == null) return Binding.DoNothing;

        int result;
        if ((bool)value && int.TryParse(parameter.ToString(), out result))
        {
            return result;
        }

        return Binding.DoNothing;
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question