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>
Код класса BaseViewModelpublic 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;
}
}