This one is driving me crazy and I am sure there must be a straightforward answer (that I haven't been able to spot).
I have a grouped gridview control which uses a VariableSizedWrapGrid for the grouped panel. The designs approved by my client include a top and bottom border on each group. I thought I could do one of two things:
Specify the border on the VariableSizedWrapGrid; or
Create a line in the GroupStyle.HeaderTemplate and apply the same to a footer.
So it seems I can't do either of those things as VariableSizedWrapGrid inherits from Panel which doesn't support the border property (only adding the border as a child element) and the GridView class doesn't include a grouped footer property. Is there a way of applying a border to the VariableSizedWrapGrid? Xaml is quite new to me as I normally specialise in server side code rather than presentation.
If I've understood you correctly they what you are trying to achieve is something like this:
This is the code for that, and it should work with a variablesizegrid as well. If I've missunderstood please add some more details and the code you already have so we can see how we can best help you.
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="App14.ItemsPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App14"
xmlns:data="using:App14.Data"
xmlns:common="using:App14.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<CollectionViewSource x:Name="groups" IsSourceGrouped="true" />
</Page.Resources>
<Grid Style="{StaticResource LayoutRootStyle}">
<Grid.Resources>
<DataTemplate x:Key="groupTemplate">
<Grid>
<Border BorderBrush="White" BorderThickness="0,10" Padding="20">
<StackPanel >
<Border Background="DarkGreen" Padding="10" Margin="10">
<TextBlock Text="{Binding Name}"/>
</Border>
<Border Background="Yellow" Padding="10" Margin="10">
<Image Width="100" Height="100" Stretch="Uniform" Source="{Binding Image}"/>
</Border>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="140"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemsGridView"
AutomationProperties.Name="Items"
TabIndex="1"
Grid.RowSpan="2"
Padding="116,136,116,46"
ItemsSource="{Binding Source={StaticResource groups}}"
ItemTemplate="{StaticResource groupTemplate}">
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="10">
<TextBlock Text='{Binding Key}' Foreground="White" FontSize="25" Margin="5" />
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
</Grid>
and the code:
namespace App14
{
public sealed partial class ItemsPage : App14.Common.LayoutAwarePage
{
public ItemsPage()
{
this.InitializeComponent();
groups.Source = GetAllGrouped(LoadCats());
}
public IEnumerable<IGrouping<string, FakeCat>> GetAllGrouped(IEnumerable<FakeCat> cats)
{
return cats.OrderBy(x => x.Name).GroupBy(x => x.Name);
}
IEnumerable<FakeCat> LoadCats()
{
return new List<FakeCat>
{
new FakeCat {Name = "Naomi", Image = "../Assets/cat1.jpg"},
new FakeCat {Name = "Naomi", Image = "../Assets/cat2.jpg"},
new FakeCat {Name = "Peter", Image = "../Assets/cat3.jpg"},
new FakeCat {Name = "Spencer", Image = "../Assets/cat4.jpg"},
};
}
}
public class FakeCat
{
public string Name { get; set; }
public string Image { get; set; }
public int ItemSize { get; set; }
}
}
Problem solved! I guess I was having trouble figuring out what controls the templates for the group rather than the actual items. I would like to take credit for solving this, but the answer came courtesy of a member of a LinkedIn group. The following style works when applied to the GridView's GroupStyle's ContainerStyle:
<Style x:Key="GroupItemStyle1" TargetType="GroupItem">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupItem">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentControl x:Name="HeaderContent" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTransitions="{TemplateBinding ContentTransitions}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" Content="{TemplateBinding Content}" IsTabStop="False" Margin="{TemplateBinding Padding}" TabIndex="0"/>
<Rectangle VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="1" Fill="White" Margin="5,0,15,0" />
<ItemsControl x:Name="ItemsControl" IsTabStop="False" ItemsSource="{Binding GroupItems}" Grid.Row="1" TabIndex="1" TabNavigation="Once">
<ItemsControl.ItemContainerTransitions>
<TransitionCollection>
<AddDeleteThemeTransition/>
<ContentThemeTransition/>
<ReorderThemeTransition/>
<EntranceThemeTransition IsStaggeringEnabled="False"/>
</TransitionCollection>
</ItemsControl.ItemContainerTransitions>
</ItemsControl>
<Rectangle Grid.Row="1" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Height="1" Fill="White" Margin="5,0,15,0" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And then in the XAML for the GridView:
<GridView.GroupStyle>
<GroupStyle HidesIfEmpty="True" ContainerStyle="{StaticResource GroupItemStyle1}">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<!-- Header Template here -->
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical" Margin="0,0,0,0"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
Related
I want to scale text and image content.I want to an output like that :
But result like that:
My code is below. What is the problem?
<UserControl.Resources>
<DataTemplate x:Key="ImageTemplate" x:DataType="model:NoteBlock">
<Grid>
<Viewbox Stretch="UniformToFill" StretchDirection="Both" Grid.Row="0">
<ScrollViewer MinZoomFactor="1" MaxZoomFactor="3" VerticalScrollMode="Disabled" HorizontalScrollMode="Disabled">
<Image HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Margin="0" Source="{x:Bind BlockData}" Holding="Image_Holding" PointerPressed="Image_PointerPressed" />
</ScrollViewer>
</Viewbox>
</Grid>
</DataTemplate>
<DataTemplate x:Key="TextTemplate" x:DataType="model:NoteBlock">
<Grid>
<Viewbox StretchDirection="Both" Stretch="Uniform" VerticalAlignment="Top">
<RichEditBox Name="richEditor" BorderThickness="0" l:RtfText.RichText="{x:Bind BlockData}" Margin="0" GotFocus="richEditor_GotFocus" >
</RichEditBox>
</Viewbox>
</Grid>
</DataTemplate>
<DataTemplate x:Key="GapTemplate">
<Grid Height="20" >
</Grid>
</DataTemplate>
<l:NoteTypeTemplateSelector x:Key="NoteTypeTemplateSelector"
TextTemplate="{StaticResource TextTemplate}"
ImageTemplate="{StaticResource ImageTemplate}"
GapTemplate="{StaticResource GapTemplate}"></l:NoteTypeTemplateSelector>
</UserControl.Resources>
<Grid Name="ContainerGrid" Background="White" PointerPressed="ContainerGrid_PointerPressed" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<ToggleSwitch Margin="0" Name="Mode" HorizontalAlignment="Right" OffContent="Read Mode" OnContent="Edit Mode"></ToggleSwitch>
<ListView x:Name="NoteList" Background="Transparent"
Grid.Row="1"
ItemsSource="{x:Bind ds}"
ItemTemplateSelector="{StaticResource NoteTypeTemplateSelector}"
ScrollViewer.VerticalScrollMode="Enabled">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
<SwapChainPanel Name="DxPanel" Grid.Row="0"></SwapChainPanel>
</Grid>
</UserControl>
Could you please help about that?
You can try using one of the Transform for your "ImageTemplate" and "TextTemplate" to scale the image/Text.
https://learn.microsoft.com/en-us/windows/uwp/graphics/transforms-overview
I think ScaleTransform should solve your problem.
I have this ListBox with custom elements and I want them to stretch to take all the available area. This is my code; currently the items only take the space that they need and I have some unused space on the left and the right side of the screen. Why?
<ListBox x:Name="listBox" Margin="0,6,0,0">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<local:ListTemplateSelector Content="{Binding}">
<local:ListTemplateSelector.bloccato>
<DataTemplate>
<StackPanel Grid.Row="1">
<Grid Background="Beige">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="/Assets/Images/locked.png" Width="40" Height="40" HorizontalAlignment="Left"/>
<TextBlock Grid.Column="1" Text="{Binding nomePacchetto}" FontFamily="./Assets/neo-normal.ttf#NEOTERIC" FontSize="48" VerticalAlignment="Bottom" Foreground="#FF373737"/>
</Grid>
<Line Stroke="DarkGray" X2="400" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,6,0,6"/>
</StackPanel>
</DataTemplate>
</local:ListTemplateSelector.bloccato>
<local:ListTemplateSelector.sbloccato>
<DataTemplate>
<StackPanel Grid.Row="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="left" Foreground="#FF5B5B5B"><Run FontSize="32" Text="1/"/> <Run FontSize="20" Text="40"/></TextBlock>
<TextBlock Grid.Column="1" Text="{Binding nomePacchetto}" FontFamily="./Assets/neo-normal.ttf#NEOTERIC" FontSize="48" VerticalAlignment="Bottom" Foreground="#FF373737"/>
</Grid>
<Line Stroke="DarkGray" X2="400" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,6,0,6"/>
</StackPanel>
</DataTemplate>
</local:ListTemplateSelector.sbloccato>
</local:ListTemplateSelector>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
There are two ways to solve this problem:
(1)
The easiest way is giving fixed width to your root grid in datatemplate. Though you'll provide fixed width, it will be resolution responsive.
Check this example:
// XAML page
<ListBox x:Name="lbxTest" Margin="12">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="Blue" Width="370" >
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
If you write your code behind like this:
List<string> lstString = new List<string>() { "string 1", "string 2", "string 3" };
lbxTest.ItemsSource = lstString;
Then in every resolution (480x800, 720x1280, 768x1280, 1080x1920), the size obtained by ListBox will be same.
check the screenshots for refference.
screenshot in 480x800
screenshot in 768x1280
(2)
The other way to solve this problem is adding one parameter in the ItemSource we'll be assigning to the ListBox.
<ListBox x:Name="lbxTest" Margin="12">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="Blue" Width="{Binding width}" >
<!--Width="370"-->
<TextBlock Text="{Binding text}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
// code behind
public class Model
{
public double width { get; set; }
public string text { get; set; }
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Model m1 = new Model()
{
text = "string 1",
width = lbxTest.ActualWidth
};
Model m2 = new Model()
{
text = "string 2",
width = lbxTest.ActualWidth
};
List<Model> lstModel = new List<Model>();
lstModel.Add(m1);
lstModel.Add(m2);
lbxTest.ItemsSource = lstModel;
}
Hope this will help..!!
There are two properties that should work but they do not (HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch")
To solve that this example will help you with the witdh:
<ListBox x:Name="ListBoxInstance" HorizontalAlignment="Stretch" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background="Green" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="{Binding ActualWidth, ElementName=ListBoxInstance, Mode=OneWay}" >
<Border Background="Red" >
<TextBlock Text="{Binding}"/>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Items>
<x:String>This is a test</x:String>
<x:String>This is the second</x:String>
<x:String>This is the thidr</x:String>
<x:String>s</x:String>
</ListBox.Items>
</ListBox>
As you see with
Width="{Binding ActualWidth, ElementName=ListBoxInstance}"
You have the content to the full width.
In some others cases (depending on the platform)
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
As the title says I get a XamlParseException when I try to run the app. I have only just started learning xaml and am currently following a tutorial from a book called Windows Phone 8 game development here is the exception it is giving me.
System.Windows.Markup.XamlParseException occurred
HResult=-2146233087
Message=The property 'System.Windows.Controls.Panel.Children' is set more than once. [Line: 53 Position: 74]
Source=System.Windows
LineNumber=53
LinePosition=74
StackTrace:
at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
at SpaceAim3D.Views.MenuPage.InitializeComponent()
at SpaceAim3D.Views.MenuPage..ctor()
InnerException:
here is my code
public partial class MenuPage : PhoneApplicationPage
{
private Dictionary<String, String> m_urls = new Dictionary<string, string>();
public MenuPage()
{
InitializeComponent();
m_urls["play"] = "/Views/GamePage.xaml";
m_urls["ranks"] = "/Views/RanksPage.xaml";
m_urls["map"] = "/Views/MapPage.xaml";
m_urls["world"] = "/Views/WorldPage.xaml";
m_urls["help"] = "/Views/HelpPage.xaml";
m_urls["web"] = "/Views/WebPage.xaml";
m_urls["settings"] = "/Views/SettingsPage.xaml";
}
//This is a common event handler used by all entities on menu page
private void BrdPage_Tap(object sender, GestureEventArgs e)
{
//To get the tag name we case the sender object and get the tag as a string
String page = ((Border)sender).Tag as String;
NavigationService.Navigate(new Uri(m_urls[page], UriKind.Relative));
}
}
and here is my Xaml code
<phone:PhoneApplicationPage
x:Class="SpaceAim3D.Views.MenuPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Landscape" Orientation="Landscape"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<phone:PhoneApplicationPage.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="125" />
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/Assets/asteroid.png" />
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TextBlock" x:Key="ButtonText">
<Setter Property="FontSize" Value="40"/>
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</phone:PhoneApplicationPage.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0"
Style="{StaticResource PhoneTextTitle1Style}">
Space Aim <Bold>3D</Bold>
</TextBlock>
<Grid.Background>
<ImageBrush ImageSource="/Assets/background.png" />
</Grid.Background>
<Border Grid.Row="1" Margin="10,5,536,194" Tap="BrdPage_Tap" Tag="play">
<TextBlock Style="{StaticResource ButtonText}" Text="PLAY!"/>
</Border>
<Border Margin="255,74,291,221" Grid.RowSpan="2" Tap="BrdPage_Tap" Tag="ranks">
<TextBlock Style="{StaticResource ButtonText}" Text="RANKS!" Margin="12,66,10,66" Width="160"/>
</Border>
<Border Grid.Row="1" Margin="12,162,534,37" Tap="BrdPage_Tap" Tag="map">
<TextBlock Style="{StaticResource ButtonText}" Text="MAP"/>
</Border>
<Border Grid.Row="1" Margin="238,189,308,10" Tap="BrdPage_Tap" Tag="world">
<TextBlock Style="{StaticResource ButtonText}" Text="WORLD"/>
</Border>
<Border Grid.Row="1" Margin="420,76,126,123" Tap="BrdPage_Tap" Tag="web">
<TextBlock Style="{StaticResource ButtonText}" Text="WEB"/>
</Border>
<Border Grid.Row="1" Margin="556,148,-10,51" Tap="BrdPage_Tap" Tag="help">
<TextBlock Style="{StaticResource ButtonText}" Text="HELP"/>
</Border>
<Border Margin="503,54,12,241" Grid.RowSpan="2" Tap="BrdPage_Tap" Tag="settings">
<TextBlock Style="{StaticResource ButtonText}" Text="SETTINGS"/>
</Border>
</Grid>
</phone:PhoneApplicationPage>
I moved all the xaml code with border tags above the grid.background and it worked
have in XAML a datagridtemplate column
<sdk:DataGridTemplateColumn x:Name="Urgency">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Image Source="{Binding UrgencyUri}"
VerticalAlignment="Stretch"
Stretch="UniformToFill"
Height="10" Width="10" Margin="0,0,5,0"/>
<TextBlock Text="{Binding Urgency}"/>
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
<sdk:DataGridTemplateColumn.HeaderStyle>
<Style TargetType="primitive:DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Urgency, Source={StaticResource MHVWindowResources}}" Grid.Column="0" HorizontalAlignment="Left" />
<filter:DataGridColumnFilter Grid.Column="1" HorizontalAlignment="Right" />
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</sdk:DataGridTemplateColumn.HeaderStyle>
</sdk:DataGridTemplateColumn>
I used this code below however it returns null
DataGridTemplateColumn templateColumn = dataGrid.Columns[columnIndex] as DataGridTemplateColumn;
if (templateColumn != null)
{
string header = templateColumn.Header as string;
if (header == null)
{
return null;
}
bindingPath = header;
}
Is their anything that I missed out? Thanks
I want to know how to get the column header in code behind.
Add this line:
var header = templateColumn.Header
place a break point here debug and check what the type is in the quick watch.
My bet is the header is probably never a string so it always null when you use:
string header = templateColumn.Header as string;
hope that helps
In the WPF app we are building, we have 3 groups of RadioButtons in individual StackPanels side by side. We are trying to program the following behavior. When tabbing through the form, we don't want to tab through each of the radiobuttons (standard behavior), instead we would like to tab to the "first" radiobutton in each group and have the ability to arrow up/down to the other radiobuttons (list) in each group once we tab to the group. We have set the IsTabStop=False for the radiobuttons below each of the first radiobutton in the list. This gives us the desired behavior for tabbing through each group, but this does not allow for the ability to arrow up/down the list. The arrow up/down behavior only works if the IsTabStop=True. We also tried setting the GroupName attribute of the radiobutton, but the behavior is the same as described above. In the old win forms, there was a radiobutton list control that had this behavior and we are just trying to recreate it. Does anyone have any idea as to how to recreate this behavior? Thanks in advance for your help...!
I think the KeyboardNavigation attached properties will do the trick.
I mocked up a quick WPF example in XAML (sorry for the length), using ItemsControls to group the RadioButton elements:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
x:Class="Experiment.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<Grid HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Margin="91,139,0,0">
<ItemsControl KeyboardNavigation.IsTabStop="False" KeyboardNavigation.TabNavigation="Once" KeyboardNavigation.DirectionalNavigation="Contained">
<RadioButton Content="Alpha" KeyboardNavigation.TabIndex="2"/>
<RadioButton Content="Delta" KeyboardNavigation.TabIndex="2"/>
<RadioButton Content="Gamma" IsChecked="True" KeyboardNavigation.TabIndex="1"/>
<RadioButton Content="Beta" KeyboardNavigation.TabIndex="2"/>
</ItemsControl>
</Grid>
<Grid HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Margin="244,139,0,0">
<ItemsControl KeyboardNavigation.IsTabStop="False" KeyboardNavigation.TabNavigation="Once" KeyboardNavigation.DirectionalNavigation="Contained">
<RadioButton x:Name="First" Content="Eenee" KeyboardNavigation.TabIndex="2"/>
<RadioButton x:Name="Second" Content="Meenee" IsChecked="True" KeyboardNavigation.TabIndex="1"/>
<RadioButton x:Name="Third" Content="Mynee" KeyboardNavigation.TabIndex="2"/>
<RadioButton x:Name="Fourth" Content="Moe" KeyboardNavigation.TabIndex="2"/>
</ItemsControl>
</Grid>
<Grid HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" Margin="391,139,0,0">
<ItemsControl KeyboardNavigation.IsTabStop="False" KeyboardNavigation.TabNavigation="Once" KeyboardNavigation.DirectionalNavigation="Contained">
<RadioButton Content="Extralarge" KeyboardNavigation.TabIndex="2"/>
<RadioButton Content="Large" KeyboardNavigation.TabIndex="2"/>
<RadioButton Content="Medium" KeyboardNavigation.TabIndex="2"/>
<RadioButton Content="Small" IsChecked="True" KeyboardNavigation.TabIndex="1"/>
</ItemsControl>
</Grid>
</Grid>
</Window>
A solution is to use the technique of styling a list box to look like a radio button group. Then it's possible to tab between the styled list boxes, and use arrow keys to select individual 'radio button' list box items.
Here's a complete demo which can also be downloaded as a sample application
public class RadioButtonGroupsViewModel
{
public RadioButtonGroupsViewModel()
{
Items1 = new List<string> {"One", "Two", "Three"};
Selected1 = "One";
Items2 = new List<string> {"Four", "Five", "Six"};
Selected2 = "Five";
Items3 = new List<string> {"Seven", "Eight", "Nine", "Ten"};
Selected3 = "Ten";
}
public IEnumerable<string> Items1 { get; private set; }
public string Selected1 { get; set; }
public IEnumerable<string> Items2 { get; private set; }
public string Selected2 { get; set; }
public IEnumerable<string> Items3 { get; private set; }
public string Selected3 { get; set; }
}
Xaml
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
<Page.Resources>
<Style x:Key="RadioButtonListBoxStyle" TargetType="ListBox">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<RadioButton
IsTabStop="False"
GroupName=""
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}}" >
<RadioButton.Content>
<Border VerticalAlignment=
"{TemplateBinding Control.VerticalContentAlignment}" Padding="2">
<ContentPresenter
Margin="{TemplateBinding Control.Padding}"
VerticalAlignment=
"{TemplateBinding Control.VerticalContentAlignment}"
HorizontalAlignment=
"{TemplateBinding Control.HorizontalContentAlignment}"
RecognizesAccessKey="True" />
</Border>
</RadioButton.Content>
</RadioButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Page.DataContext>
<Samples:RadioButtonGroupsViewModel />
</Page.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ListBox Style="{StaticResource RadioButtonListBoxStyle}"
ItemsSource="{Binding Items1}"
SelectedItem="{Binding Selected1}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<ListBox Grid.Row="1"
Style="{StaticResource RadioButtonListBoxStyle}"
ItemsSource="{Binding Items2}"
SelectedItem="{Binding Selected2}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<ListBox Grid.Row="2"
Style="{StaticResource RadioButtonListBoxStyle}"
ItemsSource="{Binding Items3}"
SelectedItem="{Binding Selected3}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
To change the orientation from left to right use the FlowDirection property to RightToLeft.
RadioButton is used in the group so that user can select only one option from the available options (No extra coding is required to uncheck others). Use same GroupName of the radiobuttons to mark in a group so that only one option can be selected as follows.
<RadioButton Height="16" Margin="26,18,132,0" Name="RadioButton_Option1" VerticalAlignment="Top" Background="Snow" BorderBrush="Black" GroupName="Visit_eggHeadcafe.com" Foreground="DarkBlue">ASP.net Articles </RadioButton>
<RadioButton Height="16" Margin="26,18,132,0" Name="RadioButton_Option2" VerticalAlignment="Top" Background="Snow" BorderBrush="Black" GroupName="Visit_eggHeadcafe.com" Foreground="DarkBlue">C# Articles</RadioButton>
<RadioButton Height="16" Margin="26,18,132,0" Name="RadioButton_Option3" VerticalAlignment="Top" Background="Snow" BorderBrush="Black" GroupName="Visit_eggHeadcafe.com" Foreground="DarkBlue">ADO.net Articles</RadioButton>
<RadioButton Height="17" Margin="26,18,115,0" Name="RadioButton_Option4" VerticalAlignment="Top" Background="Snow" BorderBrush="Black" GroupName="Visit_eggHeadcafe.com" Foreground="DarkBlue" Width="164">SQL Server 2005 Articles</RadioButton>
<Button Margin="26,18,132,0" Width="75" Height="20" Click="Button_Click">Open Articles</Button>
</StackPanel >