ViewMakerで生成するWPF/Silverlightコントロール(5)RadioButtonList編
WPF/SilverlightにはRadioButtonListというものはないのですが、ASP.NETではよく利用させてもらっていたので、RadioButtonではなくRadioButtonListとして取り込みました。RadioButton自体はグループの任意の1つを選択するというものなのでSelector的な概念ともマッチしますしね。
RadioButtonListコントロール
RadioButton自体はWPF/Silverlight標準で含まれています。これをListBoxのアイテムとして利用することでRadioButtonListを実現しています。WPF/Silverlightはカスタムコントロールを作成しなくてもこのコントロールテンプレート機能を利用することでコントロールのカスタマイズができます。以後で実際のXamlを載せているので興味のある方は見てください。
ViewMakerで指定可能なRadioButtonListの項目はListBox+αの以下になります。
-
- ItemsSource(一覧用のデータソース)
- SelectedValuePath(ItemsSourceで選択されたデータの値を示すプロパティのパス)
- DisplayMemberPath(ItemsSourceの各アイテムの表示に利用するプロパティのパス)
- ItemWidth(アイテム幅)
- Orientation(アイテムの配置方向)
- SelectionChangedCommand(選択データ変更時に実行するコマンド)
WPFサンプルイメージとXAMLコード
<ListBox Name="RadioButtonList1" ItemsSource="{Binding Path=ItemSource1,Mode=OneWay}" SelectedItem="{Binding Path=RadioButtonList1, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}" vg:SelectionChangedBehavior.Command="{Binding Path=SelectionChangedCommand1, Mode=OneWay}" IsTabStop="False" BorderThickness="0" xmlns:vg="clr-namespace:ViewMaker.Core.Wpf;assembly=ViewMaker.Core"> <ListBox.Resources> <Style TargetType="{x:Type ListBox}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="ItemContainerStyle"> <Setter.Value> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <RadioButton Focusable="False" IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"> <ContentPresenter /> </RadioButton> </ControlTemplate> </Setter.Value> </Setter> </Style> </Setter.Value> </Setter> </Style> </ListBox.Resources> </ListBox> <ListBox Name="RadioButtonList2" ItemsSource="{Binding Path=ItemSource2,Mode=OneWay}" SelectedValue="{Binding Path=RadioButtonList2, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}" SelectedValuePath="Key" DisplayMemberPath="Value" vg:SelectionChangedBehavior.Command="{Binding Path=SelectionChangedCommand2, Mode=OneWay}" IsTabStop="False" BorderThickness="0" xmlns:vg="clr-namespace:ViewMaker.Core.Wpf;assembly=ViewMaker.Core"> <ListBox.Resources> <Style TargetType="{x:Type ListBox}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <StackPanel Orientation="Vertical" /> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="ItemContainerStyle"> <Setter.Value> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <RadioButton Focusable="False" IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"> <ContentPresenter /> </RadioButton> </ControlTemplate> </Setter.Value> </Setter> </Style> </Setter.Value> </Setter> </Style> </ListBox.Resources> </ListBox> <ListBox Name="RadioButtonList3" SelectedItem="{Binding Path=RadioButtonList3, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}" FontSize="14" Foreground="Blue" Background="Azure" IsTabStop="False" BorderThickness="0"> <ListBoxItem Content="one" /> <ListBoxItem Content="two" /> <ListBoxItem Content="three" /> <ListBox.Resources> <Style TargetType="{x:Type ListBox}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="ItemContainerStyle"> <Setter.Value> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <RadioButton Focusable="False" IsChecked="{Binding Path=IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}" Width="150"> <ContentPresenter /> </RadioButton> </ControlTemplate> </Setter.Value> </Setter> </Style> </Setter.Value> </Setter> </Style> <Style TargetType="{x:Type RadioButton}"> <Setter Property="FontSize" Value="14" /> <Setter Property="Foreground" Value="Blue" /> <Setter Property="Background" Value="Azure"/> </Style> </ListBox.Resources> </ListBox>
SilverlightサンプルイメージとXAMLコード
<ListBox Name="RadioButtonList1" ItemsSource="{Binding Path=ItemSource1,Mode=OneWay}" SelectedItem="{Binding Path=RadioButtonList1, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}" IsTabStop="False" BorderThickness="0"> <i:Interaction.Behaviors> <vg:SelectionChangedBehavior vg:Command="{Binding Path=SelectionChangedCommand1, Mode=OneWay}" xmlns:vg="clr-namespace:ViewMaker.Core.Silverlight;assembly=SilverlightViewMaker.Core" /> </i:Interaction.Behaviors> <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <Grid Background="Transparent"> <RadioButton IsHitTestVisible="False" IsTabStop="False" IsChecked="{TemplateBinding IsSelected}"> <ContentPresenter></ContentPresenter> </RadioButton> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ListBox.ItemContainerStyle> </ListBox> <ListBox Name="RadioButtonList2" ItemsSource="{Binding Path=ItemSource2,Mode=OneWay}" SelectedValue="{Binding Path=RadioButtonList2, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}" SelectedValuePath="Key" DisplayMemberPath="Value" IsTabStop="False" BorderThickness="0"> <i:Interaction.Behaviors> <vg:SelectionChangedBehavior vg:Command="{Binding Path=SelectionChangedCommand2, Mode=OneWay}" xmlns:vg="clr-namespace:ViewMaker.Core.Silverlight;assembly=SilverlightViewMaker.Core" /> </i:Interaction.Behaviors> <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Vertical" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <Grid Background="Transparent"> <RadioButton IsHitTestVisible="False" IsTabStop="False" IsChecked="{TemplateBinding IsSelected}"> <ContentPresenter></ContentPresenter> </RadioButton> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ListBox.ItemContainerStyle> </ListBox> <ListBox Name="RadioButtonList3" SelectedItem="{Binding Path=RadioButtonList3, Mode=TwoWay, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}" FontSize="14" Foreground="Blue" Background="Azure" IsTabStop="False" BorderThickness="0"> <ListBoxItem Content="one" /> <ListBoxItem Content="two" /> <ListBoxItem Content="three" /> <ListBox.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <Grid Background="Transparent"> <RadioButton IsHitTestVisible="False" IsTabStop="False" IsChecked="{TemplateBinding IsSelected}" Width="150" FontSize="14" Foreground="Blue" Background="Azure"> <ContentPresenter></ContentPresenter> </RadioButton> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ListBox.ItemContainerStyle> </ListBox>
ViewModelコード
[View(ViewControlType.StackPanel)] [ViewProperty(StackPanelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Hidden)] [ViewLayoutGeneratorProvider("Generate")] public class RadioButtonListSample : ViewModel { [View(ViewControlType.RadioButtonList)] [ViewProperty(RadioButtonListViewControl.Properties.ItemsSource, "ItemSource1")] [ViewProperty(RadioButtonListViewControl.Properties.Orientation, LayoutOrientation.Horizontal)] [ViewProperty(RadioButtonListViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand1")] public string RadioButtonList1 { get; set; } [View(ViewControlType.Label)] [Display(Name = "Seleced Value")] [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)] public string RadioButtonList1Value { get; set; } [View(ViewControlType.RadioButtonList)] [ViewProperty(RadioButtonListViewControl.Properties.ItemsSource, "ItemSource2")] [ViewProperty(RadioButtonListViewControl.Properties.DisplayMemberPath, "Value")] [ViewProperty(RadioButtonListViewControl.Properties.SelectedValuePath, "Key")] [ViewProperty(RadioButtonListViewControl.Properties.SelectionChangedCommand, "SelectionChangedCommand2")] public string RadioButtonList2 { get; set; } [View(ViewControlType.Label)] [Display(Name = "Seleced Value")] [ViewProperty(LabelViewControl.Properties.HeaderPosition, LayoutHeaderPosition.Left)] public int RadioButtonList2Value { get; set; } [View(ViewControlType.RadioButtonList)] [ViewProperty(RadioButtonListViewControl.Properties.FontSize, 14.0)] [ViewProperty(RadioButtonListViewControl.Properties.ItemWidth, 150)] [ViewProperty(RadioButtonListViewControl.Properties.Foreground, "Blue")] [ViewProperty(RadioButtonListViewControl.Properties.Background, "Azure")] [ViewProperty(RadioButtonListViewControl.Properties.Orientation, LayoutOrientation.Horizontal)] public string RadioButtonList3 { get; set; } [Browsable(false)] public List<string> ItemSource1 { get { return new List<string>(new string[] { "ONE", "TWO", "THREE" }); } } [Browsable(false)] public Dictionary<int, string> ItemSource2 { get { var dict = new Dictionary<int, string>(); dict.Add(1, "One"); dict.Add(2, "Two"); dict.Add(3, "Three"); return dict; } } [Browsable(false)] public ICommand SelectionChangedCommand1 { get { return CreateCommand(SelectionChanged1); } } private void SelectionChanged1(object x) { var data = (object[])x; RadioButtonList1Value = (string)data[0]; OnPropertyChanged("RadioButtonList1Value"); } [Browsable(false)] public ICommand SelectionChangedCommand2 { get { return CreateCommand(SelectionChanged2); } } private void SelectionChanged2(object x) { var data = (object[])x; RadioButtonList2Value = ((KeyValuePair<int, string>)data[0]).Key; OnPropertyChanged("RadioButtonList2Value"); } public static ViewLayoutItem Generate() { var svc = ServiceLocator.GetService<IViewLayoutGenerator>(); var layout = svc.Generate(typeof(RadioButtonListSample), LayoutGenerateFlag.All & ~LayoutGenerateFlag.StaticProvider); var items = layout.FindChild("RadioButtonList3").GetControl<RadioButtonListViewControl>().ItemsList; items.Add("one"); items.Add("two"); items.Add("three"); return layout; } }