1

我想用与枚举值对应的对象填充StackPanela RadioButton。每个按钮的处理程序都应该运行一个任意计算,该计算采用相应的枚举值。

这是我想出的方法:

void EnumToRadioButtonPanel(Panel panel, Type type, Action<int> proc)
{
    Array.ForEach((int[])Enum.GetValues(type),
        val =>
        {
            var button = new RadioButton() { Content = Enum.GetName(type, val) };
            button.Click += (s, e) => proc(val);
            panel.Children.Add(button);
        });
}

例如,假设我想要RadioButtons 作为 enum FigureHorizontalAnchor。我希望每个按钮的操作来设置HorizontalAnchor特定Figure调用的属性figure。这是我调用的方式EnumToRadioButtonPanel

var figure = new Figure();

var stackPanel = new StackPanel();

EnumToRadioButtonPanel(stackPanel, typeof(FigureHorizontalAnchor),
    val =>
    {
        figure.HorizontalAnchor = (FigureHorizontalAnchor)
            Enum.ToObject(typeof(FigureHorizontalAnchor), val);
    });

我的问题是,有没有更好的方法来做到这一点?我应该改用“绑定”技术吗?RadioButton我在这里看到了一些关于 SO 的相关问题,但它们涉及在 XAML 中布置s ;我想通过 C# 中的代码来做到这一点。

这是上述内容的完整可运行演示。XAML:

<Window x:Class="EnumToRadioButtonPanel.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

</Window>

后面的代码:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace EnumToRadioButtonPanel
{
    public partial class MainWindow : Window
    {
        void EnumToRadioButtonPanel(Panel panel, Type type, Action<int> proc)
        {
            Array.ForEach((int[])Enum.GetValues(type),
                val =>
                {
                    var button = new RadioButton() { Content = Enum.GetName(type, val) };
                    button.Click += (s, e) => proc(val);
                    panel.Children.Add(button);
                });
        }

        public MainWindow()
        {
            InitializeComponent();

            var figure = new Figure();

            var stackPanel = new StackPanel();

            Content = stackPanel;

            EnumToRadioButtonPanel(stackPanel, typeof(FigureHorizontalAnchor),
                val =>
                {
                    figure.HorizontalAnchor = (FigureHorizontalAnchor)
                        Enum.ToObject(typeof(FigureHorizontalAnchor), val);
                });

            var label = new Label();

            stackPanel.Children.Add(label);

            var button = new Button() { Content = "Display" };

            button.Click += (s, e) => label.Content = figure.HorizontalAnchor;

            stackPanel.Children.Add(button);
        }
    }
}
4

2 回答 2

3

As you suggest, there is more "WPF" ways to do it.

Do not create controls by code. It was somewhat ok with WinForms, but it's not how you wanna do it in WPF.

If you want to create a collection of controls out of a list of item, use ItemsControl:

<ItemsControl Source="{Binding ItemsIWantToCreateControlsFor}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <RadioButton
        Content="{Binding APropertyDefinedInMyItem}"
        Command="{Binding ACommandDefinedInMyItemThatIsExecutedWhenPressed}"/>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>
于 2012-05-03T08:11:50.723 回答
0

这是另一个版本,EnumToRadioButtonPanel它似乎通过对类型进行泛型来产生更清晰的代码。

void EnumToRadioButtonPanel<T>(Panel panel, Action<T> proc)
{
    Array.ForEach((int[])Enum.GetValues(typeof(T)),
        val =>
        {
            var button = new RadioButton() { Content = Enum.GetName(typeof(T), val) };
            button.Click += (s, e) => proc((T)Enum.ToObject(typeof(T),val));
            panel.Children.Add(button);
        });
}

在这个版本中,调用EnumToRadioButtonPanel看起来像这样:

EnumToRadioButtonPanel<FigureHorizontalAnchor>(
    stackPanel,
    val => figure.HorizontalAnchor = val);

代替:

EnumToRadioButtonPanel(stackPanel, typeof(FigureHorizontalAnchor),
    val =>
    {
        figure.HorizontalAnchor = (FigureHorizontalAnchor)
            Enum.ToObject(typeof(FigureHorizontalAnchor), val);
    });

下面是整个例子。XAML:

<Window x:Class="EnumToRadioButtonPanel.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

</Window>

C#:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace EnumToRadioButtonPanel
{
    public partial class MainWindow : Window
    {
        void EnumToRadioButtonPanel<T>(Panel panel, Action<T> proc)
        {
            Array.ForEach((int[])Enum.GetValues(typeof(T)),
                val =>
                {
                    var button = new RadioButton() { Content = Enum.GetName(typeof(T), val) };
                    button.Click += (s, e) => proc((T)Enum.ToObject(typeof(T),val));
                    panel.Children.Add(button);
                });
        }

        public MainWindow()
        {
            InitializeComponent();

            var figure = new Figure();

            var stackPanel = new StackPanel();

            Content = stackPanel;

            EnumToRadioButtonPanel<FigureHorizontalAnchor>(
                stackPanel,
                val => figure.HorizontalAnchor = val);

            var label = new Label();

            stackPanel.Children.Add(label);

            var button = new Button() { Content = "Display" };

            button.Click += (s, e) => label.Content = figure.HorizontalAnchor;

            stackPanel.Children.Add(button);
        }
    }
}
于 2012-05-04T00:31:47.687 回答