如何将使用数据模板动态创建的单选按钮组绑定到列表?
How to bind Radio Button group created dynamically using Data Template to a List?
我有一个名为“CarEngineItems”的列表,包含“SelectableItems”对象,具有 2 个属性:ItemDescription 和 isSelected。
namespace DTOs
{
class CarEngines : INotifyPropertyChanged
{
public static List<SelectableItem> CarEngineItems { get; set; } = new List<SelectableItem>();
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
namespace Models
{
public class SelectableItem : INotifyPropertyChanged
{
public string ItemDescription { get; set; }
public bool IsSelected { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
我使用下面的用户控件为列表中的每个项目创建了一个单选按钮。
<UserControl.Resources>
<SelectableItem:SelectableItem x:Key="vm"></SelectableItem:SelectableItem>
<src:RadioButtonCheckedConverter x:Key="RadioButtonCheckedConverter" />
<CollectionViewSource
Source="{Binding Source={x:Static Application.Current}, Path=ItemDescription}"
x:Key="ListingDataView" />
<DataTemplate x:Key="GroupingHeaderTemplate">
<TextBlock Text="{Binding Path=Name}" Style="{StaticResource GroupHeaderStyle}"/>
</DataTemplate>
</UserControl.Resources>
<Grid>
<ItemsControl Name="RadioGroup" AutomationProperties.Name="RadioGroup" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding Path=ItemDescription}"
FlowDirection="RightToLeft"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Style="{DynamicResource CustomRadioButton}" Margin="20,0"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
我将此用户控件添加到我的主 window。
<uc:CommonRadioButtonGroup x:Name="EnginesGroup"></uc:CommonRadioButtonGroup>
在后面的代码中,我将此用户控件的源代码更新为:
InitializeComponent();
EnginesGroup.RadioGroup.ItemsSource = DTOs.CarEngines.CarEngineItems;
CarEngineItems 是在启动时添加的。
CarEngines.CarEngineItems.Add(new SelectableItem
{
ItemDescription = "V8",
IsSelected = Properties.Settings.Default.Engines.Equals("V8")
});
CarEngines.CarEngineItems.Add(new SelectableItem
{
ItemDescription = "Electric",
IsSelected = Properties.Settings.Default.Engines.Equals("Electric")
});
当前输出结果如下:
启动时,默认值 V8 按预期 selected。
Proper binding happens on startup.
但是在单击组中的下一个项目时,它也是 selected。
Why are both selected?
最终目标是 select 一个复选框(动态创建)并在按下按钮时仅将 selected 项目更新为 属性 table(保存按钮)。但在这种情况下,select离子发生在所有项目上。
根据@o_w的评论,我正在更新答案。
我通过将组名称绑定到 SelectableItem 的另一个 属性,将组名称添加到单选按钮组。
<ItemsControl Name="RadioGroup" AutomationProperties.Name="RadioGroup" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton
GroupName="{Binding Path=ItemType}"
Content="{Binding Path=ItemDescription}"
FlowDirection="RightToLeft"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"
Style="{DynamicResource CustomRadioButton}" Margin="20,0"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这是更新后的 SelectableItem。
namespace Models
{
public class SelectableItem : INotifyPropertyChanged
{
public string ItemDescription { get; set; }
public bool IsSelected { get; set; }
public string ItemType { get; set; }//New
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
我有一个名为“CarEngineItems”的列表,包含“SelectableItems”对象,具有 2 个属性:ItemDescription 和 isSelected。
namespace DTOs
{
class CarEngines : INotifyPropertyChanged
{
public static List<SelectableItem> CarEngineItems { get; set; } = new List<SelectableItem>();
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
namespace Models
{
public class SelectableItem : INotifyPropertyChanged
{
public string ItemDescription { get; set; }
public bool IsSelected { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
我使用下面的用户控件为列表中的每个项目创建了一个单选按钮。
<UserControl.Resources>
<SelectableItem:SelectableItem x:Key="vm"></SelectableItem:SelectableItem>
<src:RadioButtonCheckedConverter x:Key="RadioButtonCheckedConverter" />
<CollectionViewSource
Source="{Binding Source={x:Static Application.Current}, Path=ItemDescription}"
x:Key="ListingDataView" />
<DataTemplate x:Key="GroupingHeaderTemplate">
<TextBlock Text="{Binding Path=Name}" Style="{StaticResource GroupHeaderStyle}"/>
</DataTemplate>
</UserControl.Resources>
<Grid>
<ItemsControl Name="RadioGroup" AutomationProperties.Name="RadioGroup" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding Path=ItemDescription}"
FlowDirection="RightToLeft"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Style="{DynamicResource CustomRadioButton}" Margin="20,0"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
我将此用户控件添加到我的主 window。
<uc:CommonRadioButtonGroup x:Name="EnginesGroup"></uc:CommonRadioButtonGroup>
在后面的代码中,我将此用户控件的源代码更新为:
InitializeComponent();
EnginesGroup.RadioGroup.ItemsSource = DTOs.CarEngines.CarEngineItems;
CarEngineItems 是在启动时添加的。
CarEngines.CarEngineItems.Add(new SelectableItem
{
ItemDescription = "V8",
IsSelected = Properties.Settings.Default.Engines.Equals("V8")
});
CarEngines.CarEngineItems.Add(new SelectableItem
{
ItemDescription = "Electric",
IsSelected = Properties.Settings.Default.Engines.Equals("Electric")
});
当前输出结果如下: 启动时,默认值 V8 按预期 selected。
Proper binding happens on startup.
但是在单击组中的下一个项目时,它也是 selected。
Why are both selected?
最终目标是 select 一个复选框(动态创建)并在按下按钮时仅将 selected 项目更新为 属性 table(保存按钮)。但在这种情况下,select离子发生在所有项目上。
根据@o_w的评论,我正在更新答案。
我通过将组名称绑定到 SelectableItem 的另一个 属性,将组名称添加到单选按钮组。
<ItemsControl Name="RadioGroup" AutomationProperties.Name="RadioGroup" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton
GroupName="{Binding Path=ItemType}"
Content="{Binding Path=ItemDescription}"
FlowDirection="RightToLeft"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"
Style="{DynamicResource CustomRadioButton}" Margin="20,0"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这是更新后的 SelectableItem。
namespace Models
{
public class SelectableItem : INotifyPropertyChanged
{
public string ItemDescription { get; set; }
public bool IsSelected { get; set; }
public string ItemType { get; set; }//New
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}