我是一名C ++开发人员,目前正在开发一个WPF应用程序,我必须动态生成4个单选按钮,每个按钮都有不同的标题名称。我正在关注MVVM模式。
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<RadioButton Grid.Row="0" Content="{Binding RadioBase}" IsChecked="{Binding BaseCheck}" Height="15" Width="80" HorizontalAlignment="Center" Margin="0,0,0,0" VerticalAlignment="Center" />
<Button Grid.Row="1" Content="Refresh Regs" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0" Width="100" Height="25" />
</Grid>
现在,如果您注意到我的XAMl,我的Grid.Row="0"
中只有一个单选按钮。理想情况下,我希望生成它4次并设置绑定到Content
和IsChecked
,以便我给出4个不同的Content
。
视图模型:
private bool sBaseCheck;
public bool BaseCheck
{
get { return this.sBaseCheck; }
set
{
this.sBaseCheck= value;
this.OnPropertyChanged("BaseCheck");
}
}
private string _RadioBase;
public string RadioBase
{
get
{
return _RadioBase;
}
set
{
_RadioBase= value;
OnPropertyChanged("RadioBase");
}
}
我在C ++应用程序中完成了以下操作:
for(i = 0; i < 4; i++)
{
m_registerBase[i] = new ToggleButton(("Base 0x")+String::toHexString(i * 0x40));
addAndMakeVisible(m_registerBase[i]);
m_registerBase[i]->addButtonListener(this);
}
如果你注意到这里,它会创建它4次并有一个buttonLlick事件。它创建标题如下:
如何在我的WPF应用程序中实现这样的目标? :)如果你们帮我解决这个问题,我将不胜感激? :)
由于
答案 0 :(得分:1)
根据您的评论,我创建了一个完整的示例:
型号:
namespace WpfApplication1
{
public class RB
{
public bool BaseCheck { get; set; }
public string RadioBase { get; set; }
}
}
RBVM:
namespace WpfApplication1
{
public class RBVM : INotifyPropertyChanged
{
public RBVM()
{
_rb = new RB();
}
private RB _rb;
public RB RB
{
get
{
return _rb;
}
set
{
_rb = value;
}
}
public bool BaseCheck
{
get
{
return RB.BaseCheck;
}
set
{
RB.BaseCheck = value;
RaisePropertyChanged("BaseCheck");
}
}
public string RadioBase
{
get
{
return RB.RadioBase;
}
set
{
RB.RadioBase = value;
RaisePropertyChanged("RadioBase");
}
}
public event PropertyChangedEventHandler PropertyChanged;
#region Methods
private void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
视图模型:
namespace WpfApplication1
{
public class RBViewModel : INotifyPropertyChanged
{
public void AddRb(string content, bool isChk)
{
_rbs.Add(new RBVM() { RadioBase = content, BaseCheck = isChk });
}
public void ClearAllValues() {
foreach (RBVM item in _rbs)
{
item.BaseCheck = false;
}
}
public RBVM GetChecked() {
foreach (RBVM item in _rbs)
{
if (item.BaseCheck) {
return item;
}
}
return null;
}
private ObservableCollection<RBVM> _rbs = new ObservableCollection<RBVM>();
public ObservableCollection<RBVM> Rbs
{
get
{
return _rbs;
}
set
{
_rbs = value;
}
}
public event PropertyChangedEventHandler PropertyChanged;
#region Methods
private void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
XAML
<Window x:Class="WpfApplication1.MainWindow1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow1" Height="300" Width="300">
<Window.DataContext>
<local:RBViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="RadioDataTemplate">
<StackPanel>
<RadioButton GroupName="someGroup" Content="{Binding RadioBase}" IsChecked="{Binding BaseCheck}" Height="15" Width="80" HorizontalAlignment="Center" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid x:Name="main">
<ItemsControl ItemsSource="{Binding Rbs}" ItemTemplate="{StaticResource RadioDataTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel x:Name="radios" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<Button Width="50" Height="10" x:Name="test" Click="test_Click" ></Button>
</Grid>
</Window>
XAML代码背后:
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow1.xaml
/// </summary>
public partial class MainWindow1 : Window
{
RBViewModel _viewModel;
public MainWindow1()
{
InitializeComponent();
_viewModel = (RBViewModel)base.DataContext;
for (int i = 0; i < 4; i++)
{
_viewModel.AddRb("a" + i, true);
}
}
private void test_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine(_viewModel.GetChecked().RadioBase);
_viewModel.ClearAllValues();
}
}
}
答案 1 :(得分:1)
如果您想坚持使用MVVM模式,则应考虑将Grid
控件替换为ItemsControl
。然后,您需要两个视图模型:您在问题中解释的子视图模型和包含子视图模型集合的父视图模型:
public ObservableCollection<FPGAViewModel> Children { get; set; }
public ParentViewModel()
{
Children = new ObservableCollection<FPGAViewModel>();
Children.Add(new FPGAViewModel() { RadioBase = "Base 0x0" });
Children.Add(new FPGAViewModel() { RadioBase = "Base 0x40" });
Children.Add(new FPGAViewModel() { RadioBase = "Base 0x80" });
Children.Add(new FPGAViewModel() { RadioBase = "Base 0xc0" });
}
如果您希望能够动态添加和删除子项目,您应该使用基于ObservableCollection<T>
的集合,但似乎您想要坚持正好四个子项目。
ItemsControl
可以根据ItemTemplate
中每个项目的模板(ItemsSource
)生成项目。这些项目将放置在ItemsPanel
中,默认情况下为StackPanel
。将单选按钮堆叠在每个按钮上可能就是你想要的。
<ItemsControl ItemsSource="{Binding Children}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"
IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding RadioBase}" Margin="0,10,0,0" IsChecked="{Binding BaseCheck}" Height="15" Width="80" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
请注意,DataContext
的{{1}}应设置为ItemsControl
的实例。在MVVM中,这是通过将包含ParentViewModel
的视图绑定到父视图模型来完成的。当ItemsControl
生成子项时,每个ItemsControl
将RadioButton
绑定到每个DataContext
实例,ChildViewModel
中的绑定将绑定到该视图模型。
答案 2 :(得分:0)
for(i = 0; i < 4; i++)
{
m_registerBase[i] = new RadioButton();
m_registerBase[i].IsChecked=true;
//Sets the Binding programmatcially
m_registerBase[i].SetBinding(RadioButton.Content, "MyContent");
}
答案 3 :(得分:0)
Yopu可以使用以下RadioBox
&amp;成功动态生成分组XAML
es。 Binding
<强> XAML:强>
<ListBox SelectionMode="Single"
SelectedValue="{Binding CurrentRadioDescription}"
SelectedValuePath="Description"
ItemsSource="{Binding RadioBoxModelList}"
Focusable="True"
KeyboardNavigation.IsTabStop="True"
VerticalAlignment="Center"
BorderBrush="Transparent"
BorderThickness="0"
Background="Transparent" >
<ListBox.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlDarkBrushKey}"
Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveBorderBrushKey}"
Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlDarkDarkBrushKey}"
Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlLightBrushKey}"
Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlLightLightBrushKey}"
Color="Transparent"/>
<SolidColorBrush x:Key="{x:Static SystemColors.WindowBrushKey}"
Color="Transparent"/>
</ListBox.Resources>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal"
Background="Transparent"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<RadioButton
MinWidth="80"
Background="Transparent"
IsChecked="{Binding Path=IsSelected,
RelativeSource={RelativeSource
AncestorType={x:Type ListBoxItem}},
Mode=TwoWay}"
Content="{Binding Description, Mode=OneWay}"
Margin="-1"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<强> C#强>
public class RadioBoxModel : INotifyPropertyChanged {
//Raise property changed notifications in Setters below.
public bool IsChecked { get; set; }
public string Description { get; set; }
}