Avoiding spaces while grouping with listbox - wpf

I am using listbox grouping, I want to avoid vertical spaces left between header and subelements, as shown below:
Here is the xaml for the same
<Grid>
<Grid.Resources>
<XmlDataProvider x:Key="Company" XPath="/Company">
<x:XData>
<Company xmlns="">
<Person Name="Jack" Role="CEO"/>
<Person Name="Tim" Role="PL" />
<Person Name="Jil" Role="PL" />
<Person Name="Jimmy" Role="PM" />
<Person Name="Joy" Role="PM" />
<Person Name="Jim" Role="PL" />
<Person Name="Jack" Role="PM" />
</Company>
</x:XData>
</XmlDataProvider>
<DataTemplate x:Key="categoryTemplate">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold" Background="ForestGreen" Margin="0,5,0,0"/>
</DataTemplate>
<DataTemplate x:Key="template">
<TextBlock Text="{Binding XPath=#Name}"/>
</DataTemplate>
<CollectionViewSource x:Key="cvs" Source="{Binding Source={StaticResource Company},XPath=Person}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="#Role"/>
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Grid.Resources>
<ListBox Name="lst" ItemTemplate="{StaticResource template}" ItemsSource="{Binding Source={StaticResource cvs}}">
<ListBox.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource categoryTemplate}" />
</ListBox.GroupStyle>
</ListBox>
</Grid>

The ListBox will use GroupItems when you group and they have a default Margin set to 5,0,0,0. Also, ListBoxItem comes with a default Padding of 2,0,0,0. You can change either one, or both, of them like this
<ListBox ...>
<ListBox.Resources>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<StackPanel>
<ContentPresenter/>
<ItemsPresenter Margin="0,0,0,0"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
<!--...-->
</ListBox>

Check if this is fine for you. Just modified your template bit.
<DataTemplate x:Key="template">
<TextBlock Text="{Binding XPath=#Name}" Margin="-5,0,0,0"/>
</DataTemplate>

Related

How to setup a template for a ListBox with a DataTemplate

So I have the following ListBox defined:
<ListBox Grid.Row="1" Grid.Column="0" x:Name="RawLBControl"
ItemsSource="{Binding ProductionLists.Raw}"
Background="LightGray" BorderThickness="2" BorderBrush="Black">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Mode=OneWay}" Background="LightGray"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
There are going to be a number of these, where the only things that changes is the placement (Grid location) and the ItemsSource bindings. Everything else is going to be the same. Question is how do I setup a template so all the ListBoxes use it.
You can define style in application resources and applied it to ListBox later in your code.
<Application x:Class="Q52018469.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="MyListBoxStyle" TargetType="ListBox">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBox Text="{Binding Mode=OneWay}" Background="LightGray"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
Using of this style:
...
<Grid>
...
<ListBox Grid.Row="1" Grid.Column="0" x:Name="RawLBControl"
ItemsSource="{Binding ProductionLists.Raw}"
Style="{StaticResource MyListBoxStyle}" />
</Grid>
...

WPF hover over with unique images

I want to create a Magic the Gathering trading user interface where if a user hover over a specific card name, that it will display that card's image (see image). Currently, in the MultiMasterCardListView, the only image that displays is the Black Lotus card image which I hard-coded that image path. As a result, it does not matter which card name I hover over, it only shows black lotus image.
So I created a property (PlayerCardPath) inside of MultiMasterCardListViewModel, which will loop through all the cards in the database
and test if the hover over's content/value equals that card name. If it does then return the path with the card's name and image format. The problem is that mc.Name(from MultiMasterCardViewModel) returns nothing so the "if" statement inside of the foreach doesn't get hit at all. How do I get the value of whatever is being hover over from the MultiMasterCardListView? Let me know if you need clarification. Thanks
MultiMasterCardListView:
<UserControl x:Class="OrderEntrySystem.MultiMasterCardListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OrderEntrySystem"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="600">
<UserControl.Resources>
<ResourceDictionary Source="SharedResources.xaml" />
</UserControl.Resources>
<Grid>
<DockPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" DockPanel.Dock="Top" Margin="0,0,0,5" Height="30">
<TextBox x:Name="searchTextBox" Text="{Binding Path=SearchText}" Width="100" Height="23" Margin="0,4,5,0" />
<ContentControl Content="{Binding Path=FilterCommands}" ContentTemplate="{StaticResource ResourceKey=NestedCommandTemplate}" />
</StackPanel>
<Grid DockPanel.Dock="Bottom">
<local:SelectedItemsView />
</Grid>
<Grid DockPanel.Dock="Bottom">
<local:PagingView></local:PagingView>
</Grid>
<ListView ItemsSource="{Binding Path=SortedCards}" ItemContainerStyle="{StaticResource ResourceKey=ListViewStyle}">
<ToolTipService.ToolTip>
<Border>
<StackPanel>
<Image Source="C:\Users\Teng\Documents\0515-392-team-orange\Team Magic Project\OrderEntrySystem\Images\Black Lotus.JPG"/>
</StackPanel>
</Border>
</ToolTipService.ToolTip>
<ListView.View>
<GridView>
<GridViewColumn Width="175" DisplayMemberBinding="{Binding Path=Name}">
<GridViewColumnHeader Content="Name" Command="{Binding Path=SortCommand}" CommandParameter="Name" />
</GridViewColumn>
<GridViewColumn Header="Point Value" Width="70" DisplayMemberBinding="{Binding Path=PointValue}" />
</GridView>
</ListView.View>
</ListView>
</DockPanel>
</Grid>
MultiMasterCardListViewModel:
public string PlayerCardPath
{
get
{
string result = null;
MultiMasterCardListView mC = new MultiMasterCardListView();
foreach (var card in this.repository.GetMasterCardLists())
{
if (card.Name == mC.Name)
{
result = (#"..\..\..\Images\" + mC.Name + ".JPG");
break;
}
}
return result;
}
}
SharedResources:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:OrderEntrySystem">
<DataTemplate DataType="{x:Type local:MasterCardListViewModel}">
<local:MasterCardListView></local:MasterCardListView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MemberViewModel}">
<local:MemberView></local:MemberView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MultiMasterCardListViewModel}">
<local:MultiMasterCardListView></local:MultiMasterCardListView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MultiMemberViewModel}">
<local:MultiMemberView></local:MultiMemberView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MultiMemberCardListViewModel}">
<local:MultiMemberCardListView></local:MultiMemberCardListView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:TransactionViewModel}">
<local:TransactionView></local:TransactionView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MultiTransactionViewModel}">
<local:MultiTransactionView></local:MultiTransactionView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MultiCardTransactionViewModel}">
<local:MultiCardTransactionView></local:MultiCardTransactionView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:CardConditionViewModel}">
<local:CardConditionView></local:CardConditionView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:QuantityViewModel}">
<local:QuantityView></local:QuantityView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:PurchasePointsViewModel}">
<local:PurchasePointsView></local:PurchasePointsView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MultiMyCardListViewModel}">
<local:MultiMyCardListView></local:MultiMyCardListView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MultiShoppingCartViewModel}">
<local:MultiShoppingCartView></local:MultiShoppingCartView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ShoppingCartViewModel}">
<local:ShoppingCartView></local:ShoppingCartView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ReportViewModel}">
<local:ReportView></local:ReportView>
</DataTemplate>
<DataTemplate DataType="{x:Type local:LoginViewModel}">
<local:LoginView></local:LoginView>
</DataTemplate>
<DataTemplate x:Key="WorkspacesTemplate">
<TabControl IsSynchronizedWithCurrentItem="True" Margin="4" ItemsSource="{Binding}">
<TabControl.Background>
<ImageBrush ImageSource="..\..\Images\Magicthegathering-logo.svg.png" Stretch="Uniform" AlignmentY="Bottom" AlignmentX="Center" Opacity="0.5"/>
</TabControl.Background>
<TabControl.ItemTemplate>
<DataTemplate>
<DockPanel>
<Button Command="{Binding Path=CloseCommand}" Content="X" Cursor="Hand" Margin="4,0,0,0" FontWeight="Bold" Height="16" Width="16" FontFamily="Courier" FontSize="9" DockPanel.Dock="Right" />
<ContentPresenter Content="{Binding Path=DisplayName}" VerticalAlignment="Center" />
</DockPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</DataTemplate>
<DataTemplate x:Key="NestedCommandTemplate">
<ItemsControl ItemsSource="{Binding}" HorizontalAlignment="Right">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding Path=Command}" Content="{Binding Path=DisplayName}" IsDefault="{Binding Path=IsDefault}" IsCancel="{Binding Path=IsCancel}" Height="23" Width="75" Margin="4,4,0,0" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
<DataTemplate x:Key="CommandsTemplate">
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding Path=Command}" Content="{Binding Path=DisplayName}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
<ControlTemplate x:Key="HoverOverImage">
<Border Name="border" BorderThickness="0"
Background="Transparent">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="C:\Users\Teng\Documents\0515-392-team-orange\Team Magic Project\Images\Coalition Honor Guard.JPG" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<DataTemplate x:Key="HorizontalCommandsTemplate">
<ItemsControl ItemsSource="{Binding}" HorizontalAlignment="Right">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding Path=Command}" Content="{Binding Path=DisplayName}" Height="23" Width="75" Margin="4,4,0,0" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
<Style x:Key="MainHeaderStyle" TargetType="{x:Type HeaderedContentControl}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<Border Background="{StaticResource Brush_HeaderBackground}" BorderBrush="LightGray" BorderThickness="1" CornerRadius="5" Margin="4" Padding="4" SnapsToDevicePixels="True">
<TextBlock FontSize="14" FontWeight="Bold" Foreground="White" HorizontalAlignment="Center" Text="{TemplateBinding Content}" />
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type HeaderedContentControl}">
<DockPanel>
<ContentPresenter DockPanel.Dock="Top" ContentSource="Header" ContentTemplate="{TemplateBinding HeaderTemplate}" />
<ContentPresenter ContentSource="Content" ContentTemplate="{TemplateBinding ContentTemplate}" />
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListViewStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
<Style x:Key="ValidationStyleTextBox" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}" />
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="true">
<TextBlock DockPanel.Dock="Right" VerticalAlignment="Center" Margin="5,0,0,0" Text="{Binding ElementName=customAdorner, Path=AdornedElement.(Validation.Errors).CurrentItem.ErrorContent}" />
<Border Background="Red" DockPanel.Dock="Right" Margin="5,0,0,0" Width="20" Height="20" CornerRadius="10">
<TextBlock Text="!" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" Foreground="White" />
</Border>
<AdornedElementPlaceholder Name="customAdorner" VerticalAlignment="Center">
<Border BorderBrush="Red" BorderThickness="1" />
</AdornedElementPlaceholder>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="PagingButton" TargetType="{x:Type Button}">
<Setter Property="FontFamily" Value="Webdings" />
<Setter Property="Height" Value="23" />
<Setter Property="Width" Value="45" />
<Setter Property="Margin" Value="4,0,4,0" />
</Style>
<Style x:Key="PagingTextBlock" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="4,0,4,0" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>

WPF ContentControl Styling

How can I apply a style to the content of a contentcontrol. For example:
<Window.Resources>
<Controls:DataGrid x:Key="PersonDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding .}" x:Shared="False">
<Controls:DataGrid.Columns>
<Controls:DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}" IsReadOnly="True"/>
<Controls:DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}" IsReadOnly="True"/>
</Controls:DataGrid.Columns>
</Controls:DataGrid>
</Window.Resources>
<StackPanel>
<ContentControl Content="{StaticResource PersonDataGrid}" DataContext="{Binding Path=Customers}" Style="DataGridStyle1"></ContentControl>
<ContentControl Content="{StaticResource PersonDataGrid}" DataContext="{Binding Path=Employees}" Style="DataGridStyle2"></ContentControl>
</StackPanel>
EDIT 2: It looks like you're trying to apply a different Style to each of your DataGrids. To do this, you're going to need to define their specific Style inside the Resources Section of each ContentControl. If the styles are defined elsewhere, you can always create a new style based on the style defined elsewhere as shown below
The first ContentControl's DockPanel's Background will be Black. The second's will be Blue.
<Window.Resources>
<Style TargetType="DockPanel" x:Key="DockStyle1">
<Setter Property="Background" Value="Black" />
</Style>
<Style TargetType="DockPanel" x:Key="DockStyle2">
<Setter Property="Background" Value="Blue" />
</Style>
<DockPanel x:Key="MyDockPanel">
<Rectangle Fill="Green" DockPanel.Dock="Top" Height="20" Width="50" />
<Rectangle Fill="Red" DockPanel.Dock="Top" Height="20" Width="20" />
<Rectangle Fill="Yellow" DockPanel.Dock="Bottom" Height="20" Width="50" />
</DockPanel>
</Window.Resources>
<StackPanel>
<StackPanel>
<ContentControl Content="{StaticResource MyDockPanel}">
<ContentControl.Resources>
<Style TargetType="{x:Type DockPanel}" BasedOn="{StaticResource DockStyle1}" />
</ContentControl.Resources>
</ContentControl>
<ContentControl Content="{StaticResource MyDockPanel}">
<ContentControl.Resources>
<Style TargetType="DockPanel" BasedOn="{StaticResource DockStyle2}" />
</ContentControl.Resources>
</ContentControl>
</StackPanel>
</StackPanel>
EDIT 3 - For your example, I think you want something like this (I can't test this however as I don't have access to your 'Controls' namespace):
<Window.Resources>
<Controls:DataGrid x:Key="PersonDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding .}" x:Shared="False">
<Controls:DataGrid.Columns>
<Controls:DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}" IsReadOnly="True"/>
<Controls:DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}" IsReadOnly="True"/>
</Controls:DataGrid.Columns>
</Controls:DataGrid>
</Window.Resources>
<StackPanel>
<ContentControl Content="{StaticResource PersonDataGrid}" DataContext="{Binding Path=Customers}">
<ContentControl.Resources>
<Style TargetType="{x:Type Controls:DataGrid}" BasedOn="{StaticResource DataGridStyle1}" />
</ContentControl.Resources>
</ContentControl>
<ContentControl Content="{StaticResource PersonDataGrid}" DataContext="{Binding Path=Employees}">
<ContentControl.Resources>
<Style TargetType="{x:Type Controls:DataGrid}" BasedOn="{StaticResource DataGridStyle2}" />
</ContentControl.Resources>
</ContentControl>
</StackPanel>
Unfortunately, you cannot Style DataGridTextColumns as stated in Why can't I style a DataGridTextColumn?
Instead, I generally set the CellStyle of a DataGridTextColumn to 'style' it:
<Style TargetType="DataGridCell" x:Key="DataGridCenteredText">
<Setter Property="TextBlock.TextAlignment" Value="Center" />
</Style>
<DataGridTextColumn Header="Centered Text" CellStyle="{StaticResource DataGridCenteredText}" Binding="{Binding Path=MyData}" />
I think you'll need to define the CellStyle on a per column basis however (I can't think of any reason why you wouldn't anyway.)

CollectionViewSource+PropertyGroupDescription - count of items in a group

In my WPF application I have a CollectionViewSource which is providing a view to a private ObservableCollection. The CollectionViewSource has a PropertyGroupDescription which is utilised in a ListBox to present data to the User's preference.
Using a ControlTemplate containing a Expander Control within the ListBox GroupStyle, the result is quite nice. However, I would like to show the number of items in each group in the Expander Header in addition to the Group Name. Any ideas on the binding path?
Regards,
Liam
<Style x:Key="basicGroupStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Header="{Binding Name}" IsExpanded="True">
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ListBox ItemsSource="{Binding Source={StaticResource myViewSource}}">
<ListBox.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource basicGroupStyle}"/>
</ListBox.GroupStyle>
</ListBox>
you have to use property ItemCount
<Window x:Class="WpfApplication11.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<XmlDataProvider x:Key="data">
<x:XData>
<Animals xmlns="">
<Animal name="Dory" Species="Fish" />
<Animal name="Felix" Species="Cat" />
<Animal name="Fluffy" Species="Dog" />
<Animal name="Jake" Species="Snake" />
<Animal name="Mittens" Species="Cat" />
<Animal name="Murtle" Species="Turtle" />
<Animal name="Nemo" Species="Fish" />
<Animal name="Rex" Species="Dog" />
<Animal name="Rover" Species="Dog" />
<Animal name="Toonces" Species="Cat" />
</Animals>
</x:XData>
</XmlDataProvider>
<CollectionViewSource x:Key="animalsBySpecies" Source="{Binding Source={StaticResource data}, XPath=Animals/Animal}">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="#Species" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
<DockPanel>
<ScrollViewer DockPanel.Dock="Bottom" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Source={StaticResource animalsBySpecies}}">
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<GroupBox >
<GroupBox.Header>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text ="{Binding Name}" ></TextBlock>
<TextBlock Text="(" Grid.Column="1" Margin="15,0,0,0"></TextBlock>
<TextBlock Text="{Binding ItemCount}" Grid.Column="1" Margin="20,0,0,0"
HorizontalAlignment="Right" ></TextBlock>
<TextBlock Text=")" Margin="0,0,-5,0" Grid.Column="1
HorizontalAlignment="Right" ></TextBlock>
</Grid>
</GroupBox.Header>
<ItemsPresenter />
</GroupBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding XPath=#name}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Window>
I updated the Group Style as follows. I found that I could not use a MultiBinding in the Expander.Header property, nothing was displayed on screen, I needed to include an intermediate TextBlock instead.
<Style x:Key="basicGroupStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True">
<Expander.Header>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Name"/>
<Binding Path="ItemCount"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Expander.Header>
<ItemsPresenter/>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How to implement a XAML Radio Button control with an ObservableCollection source?

I have the following ComboBox element in XAML:
<ComboBox ItemsSource="{Binding CollectionControlValues}"
SelectedItem="{Binding CollectionControlSelectedValue, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I would like to implement RadioButtons in the same way, like this:
PSEUDO-CODE:
<RadioButtons ItemsSource="{Binding CollectionControlValues}"
SelectedItem="{Binding CollectionControlSelectedValue, UpdateSourceTrigger=PropertyChanged}">
<RadioButtons .ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}" />
</DataTemplate>
</RadioButtons .ItemTemplate>
</RadioButtons >
However, the only WPF RadioButton implementations I can find are static like this.
<StackPanel x:Name="rbHolder1" Style="{StaticResource rbStackPanelStyle}">
<RadioButton Style="{StaticResource rbStyle}">RadioButton 1</RadioButton>
<RadioButton Style="{StaticResource rbStyle}">RadioButton 2</RadioButton>
<RadioButton Style="{StaticResource rbStyle}">RadioButton 3</RadioButton>
<RadioButton Style="{StaticResource rbStyle}">...</RadioButton>
</StackPanel>
How can I create a RadioButton control which is not static like the above but instead gets its data from its ItemsSource property as in the above ComboBox example?
Use ItemsControl and DataTemplate:
<ItemsControl ItemsSource="{Binding CollectionControlValues}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Content="{Binding Value}" IsChecked="{Binding SomeProperty}" GroupName="name"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
code in window1.xaml file
<Window x="RadioButton.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local ="clr-namespace:RadioButton"
Title="Window1" Height="300" Width="300" Loaded="Window_Loaded">
<StackPanel>
<StackPanel.Resources>
<ObjectDataProvider x:Key="RadioOptions" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:RadioOption" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<Style x:Key="RadioButtonList" TargetType="{x:Type ListBox}">
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Background="Transparent">
<RadioButton Focusable="False"
IsHitTestVisible="False"
IsChecked="{TemplateBinding IsSelected}">
<ContentPresenter />
</RadioButton>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<ListBox Margin="37,20,28,58" Name="listBox1" Style="{StaticResource RadioButtonList}" ItemsSource="{Binding Source={StaticResource RadioOptions}}" />
</StackPanel>
this line
<ListBox` Margin="37,20,28,58" Name="listBox1" Style="{StaticResource RadioButtonList}"
ItemsSource="{Binding Source={StaticResource RadioOptions}}"
is using itemsource property
C# code
namespace RadioButton
{
public enum RadioOption
{
option1,
option2,
option3,
option4
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
}
i think this will help you out..

Resources