Задать вопрос

Как обработать событие из DataTemplate нажатия радиокнопок?

Этот DataTemplate находится в ListBoxItem через 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>

Есть идеи, как передать событие нажатия радиокнопок в код? Я пробовал через инициализацию в коде прицепить метод к ним. Не работает. Пробовал через DataContext передавать. Тоже не работает.
  • Вопрос задан
  • 120 просмотров
Подписаться 1 Средний 10 комментариев
Решения вопроса 1
lexxpavlov
@lexxpavlov
Программист, преподаватель
ListBox (как и другой наследник ItemsControl) имеет список элементов (удобнее всего его указывать через ItemsSource). Каждый элемент списка строится отдельным пунктом. У каждого пункта автоматически устанавливается DataContext - тот элемент исходного списка, который строится. В DataTemplate хорошо и правильно указывать нужный тип, который будет у элемента в датаконтексте, тогда появится подсказка у {Binding} внутри шаблона.

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
public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Код конвертера
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;
    }
}

Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы