生成具有不同“内容”的单选按钮

时间:2012-10-25 07:10:21

标签: c# c++ .net wpf radio-button

我是一名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次并设置绑定到ContentIsChecked,以便我给出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事件。它创建标题如下:

  • 按钮1 =基数0x0(因为i = 0且toHexString将0x0转换为0)
  • 按钮2 =基本0x40(因为i = 1而toHexString将0x40转换为 40)
  • 按钮3 =基本0x80(因为i = 2且toHexString转换为0x80 到80)
  • 按钮4 =基本0xc0(因为i = 3且toHexString转换 0xc0到c0)

如何在我的WPF应用程序中实现这样的目标? :)如果你们帮我解决这个问题,我将不胜感激? :)

由于

4 个答案:

答案 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生成子项时,每个ItemsControlRadioButton绑定到每个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");
}

The RadioButton Class

SetBinding

答案 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; }
}