0

我是一名 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 次并有一个 buttonclick 事件。它创建标题如下:

  • 按钮 1 = Base 0x0(因为 i = 0 并且 toHexString 将 0x0 转换为 0)
  • 按钮 2 = Base 0x40(因为 i = 1 并且 toHexString 将 0x40 转换为 40)
  • 按钮 3 = Base 0x80(因为 i = 2 并且 toHexString 将 0x80 转换为 80)
  • 按钮 4 = Base 0xc0(因为 i = 3 并且 toHexString 将 0xc0 转换为 c0)

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

谢谢

4

4 回答 4

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();
            }



        }


    }
于 2012-10-25T07:29:40.657 回答
1

如果你想坚持 MVVM 模式,你应该考虑GridItemsControl. 然后,您需要两个视图模型:您在问题中解释的子视图模型和包含子视图模型集合的父视图模型:

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应将 的ItemsControl设置为 的实例ParentViewModel。在 MVVM 中,这是通过将包含 的视图绑定ItemsControl到父视图模型来完成的。当ItemsControl生成子项时,每个子项都RadioButtonDataContext绑定到每个ChildViewModel实例,并且其中的绑定RadioButton将绑定到该视图模型。

于 2012-10-25T08:20:01.330 回答
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");
}

单选按钮类

设置绑定

于 2012-10-25T07:24:13.043 回答
0

Yopu可以使用以下&实现分组RadioBoxes的动态生成XAMLBinding

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; }
}
于 2012-10-25T08:16:03.893 回答