2012-05-03 25 views
1

我想填充StackPanelRadioButton對象,它們對應於枚舉的值。每個按鈕的處理程序應該運行一個任意的計算,該計算使用相應的枚舉值。從C#中的枚舉創建單選按鈕

這是我想出了方法:

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

例如,假設我想RadioButton S爲枚舉FigureHorizontalAnchor。我希望每個按鈕的動作設置FigureHorizontalAnchor屬性,稱爲figure。以下是我想調用EnumToRadioButtonPanel

var figure = new Figure(); 

var stackPanel = new StackPanel(); 

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

我的問題是,有沒有更好的方式來做到這一點?我應該使用「綁定」技術嗎?我在這裏看到了幾個相關的問題,但他們涉及在XAML中佈置RadioButton;我想通過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); 
     } 
    } 
} 

回答

3

正如你提到的,還有更多的 「WPF」 的方式來做到這一點。

不要通過代碼創建控件。這與WinForms有些不錯,但它不是你想要做的WPF

如果你想創建控件的集合了項目的列表,使用ItemsControl

<ItemsControl Source="{Binding ItemsIWantToCreateControlsFor}"> 
    <ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <RadioButton 
     Content="{Binding APropertyDefinedInMyItem}" 
     Command="{Binding ACommandDefinedInMyItemThatIsExecutedWhenPressed}"/> 
    </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 
+0

喜尼古拉斯。感謝您的提示。儘管如此,從C#做這個要求是必需的。我也想瞄準在我的問題中指定的API。即在給定枚舉的情況下填充一個面板。所以我會延遲接受這個答案。 – dharmatech

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