I want to create a GroupBox with a custom header, where besides the header title, i want to have an icon that is associated with a certain MVVM binding.
For example i got it working using this approach:
View:
<GroupBox>
<GroupBox.Header>
<StackPanel Orientation="Horizontal">
<Image Height="18" VerticalAlignment="Center" Source="{Binding BondHead2Enabled, Converter={StaticResource StateToIconConverter}}" />
<Label Content="Bond Head 2"/>
</StackPanel>
</GroupBox.Header>
<finalBondView:BondheadTemplateView Content="{Binding BondHead2Content}"/>
</GroupBox>
ViewModel
public bool BondHead2Enabled => false;
public BondHeadTemplateViewModel BondHead2Content
{
get { return _bondheadContents[1]; }
set
{
if (_bondheadContents[1] != value && value != null)
{
_bondheadContents[1] = value;
RaisePropertyChanged("BondHead2Content");
}
}
}
However with this approach i have to repeat a lot of code on each groupbox i have. So i want to turn this into a Header Template where i can just associate a style instead of copy pasting the header. Therefore i created this style:
Style
<Style x:Key="StatusGroupBox" TargetType="{x:Type GroupBox}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Height="18" VerticalAlignment="Center" Source="{Binding EnabledStatus, RelativeSource={RelativeSource AncestorType=GroupBox}, Converter={StaticResource StateToIconConverter}}" />
<Label Content="{Binding Header, RelativeSource={RelativeSource AncestorType=GroupBox}}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
ViewModel
<GroupBox Header="Bond Head 3" Margin="5" Style="{DynamicResource StatusGroupBox}">
<finalBondView:BondheadTemplateView Content="{Binding BondHead3Content}"/>
</GroupBox>
I can get the content for the label using this style, but i can't get the boolean value that i need to know which icon to display, named EnabledStatus in the style. So how can i pass this information to te style in a generic way?
After reading a bit more on the recommended topics I found a effective way to do this. Instead of binding just a String to the Header property, i binded a structure with both a Title (string) and a status (boolean). Then i read each field in the style. The code:
Support class
public class StatusHeaderTemplate
{
public string HeaderTitle { get; set; }
public bool HeaderStatus { get; set; }
public StatusHeaderTemplate(string title, bool status)
{
HeaderTitle = title;
HeaderStatus = status;
}
}
Style
<Style x:Key="MountainTopStatusGroupBox" TargetType="{x:Type GroupBox}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding HeaderStatus, Converter={StaticResource StateToIconConverter}}" />
<Label Content="{Binding HeaderTitle}"/>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
View
<GroupBox Margin="5" Header="{Binding BondHead1StatusHeader}" Style="{DynamicResource MountainTopStatusGroupBox}">
<finalBondView:BondheadTemplateView Content="{Binding BondHead1Content}"/>
</GroupBox>
ViewModel
public StatusHeaderTemplate BondHead1StatusHeader => new StatusHeaderTemplate("Bond Head 1", true);