Adding combobox to Ribbon Control in XAML - c#

I have a WPF Application with a Ribbon Control. I want to add a ComboBox, to show the logged in user next to the help button. But when I try to add the ComboBox, it is created as a Tab.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Ribbon x:Name="RibbonWin" SelectedIndex="0" Margin="0,0,0,113">
<Ribbon.HelpPaneContent>
<RibbonButton SmallImageSource="Images\help.png"></RibbonButton>
</Ribbon.HelpPaneContent>
<RibbonComboBox>
<ComboBoxItem Content="Test1"/>
</RibbonComboBox>
<RibbonTab Header="Home" KeyTip="H" Margin="0,0,0,-1" >
<RibbonGroup x:Name="ClipboardGroup" Header="Clipboard">
<RibbonMenuButton LargeImageSource="Images\paste.jpg" Label="Paste" KeyTip="V">
<RibbonMenuItem ImageSource="Images\paste.jpg" Header="Keep Text Only" KeyTip="T"/>
<RibbonMenuItem ImageSource="Images\paste.jpg" Header="Paste Special..." KeyTip="S"/>
</RibbonMenuButton>
<RibbonButton SmallImageSource="Images\cut.jpg" Label="Cut" KeyTip="X" />
<RibbonButton SmallImageSource="Images\copy.jpg" Label="Copy" KeyTip="C" />
</RibbonGroup>
<RibbonGroup x:Name="Questions" Header="Questions And Answers">
<RibbonMenuButton LargeImageSource="Images\Question.jpg" Label="Questions" KeyTip="V">
<RibbonMenuItem ImageSource="Images\paste.jpg" Header="Add Question" KeyTip="T"/>
<RibbonMenuItem ImageSource="Images\paste.jpg" Header="Paste Special..." KeyTip="S"/>
</RibbonMenuButton>
<RibbonButton SmallImageSource="Images\Save.jpg" Label="Save" KeyTip="X" />
<RibbonButton SmallImageSource="Images\Add.jpg" Label="Add" KeyTip="C" />
</RibbonGroup>
</RibbonTab>
<RibbonTab Header="Insert" KeyTip="I">
</RibbonTab>
<RibbonTab Header="PageLayout" KeyTip="L">
</RibbonTab>
</Ribbon>
</Grid>
Also is there a way to remove the the Application Menu ComboBox on the left that is created by default.

Put a RibbonApplicationMenu into the ApplicationMenu-property and set its Visibility to 'Collapsed'. This will not remove the application menu, but at least it is not longer visible. There is not other way to hide it.
The ComboBox must be inserted into a RibbonTab, so a RibbonTab will be created implicitly if you do not specify anyone.
The following example demonstrates how to hide the application menu and insert a combo box:
<Ribbon>
<Ribbon.ApplicationMenu>
<RibbonApplicationMenu Visibility="Collapsed"></RibbonApplicationMenu>
</Ribbon.ApplicationMenu>
<RibbonTab>
<RibbonGroup>
<RibbonComboBox></RibbonComboBox>
</RibbonGroup>
</RibbonTab>
</Ribbon>

I got it from my friend,
this might help you
Create your own template and add it to Ribbon HelpPaneContentTempalte
<Ribbon.HelpPaneContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="24">
<ToggleButton x:Name="btn" >
<TextBlock Text="Operator"/>
</ToggleButton>
<Popup IsOpen="{Binding IsChecked, ElementName=btn}" x:Name="Popup" StaysOpen="False" Placement="Bottom"
PlacementTarget="{Binding ElementName=btn}" Height="120" Width="150" HorizontalOffset="-90" >
<Popup.Resources>
<Style x:Key="LinkButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock>
<ContentPresenter />
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Blue" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Popup.Resources>
<Border BorderBrush="Gray" BorderThickness="2" Background="White" >
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" Height="50">
<Image Source="Images\UserPhoto.png" Height="30"/>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="Operator" FontSize="16" Margin="10,0,0,0"/>
<TextBlock Text="Operator#xxx.com" FontSize="10" Foreground="DarkGray" Margin="10,0,0,0"/>
</StackPanel>
</StackPanel>
<Separator Background="LightGray"/>
<StackPanel Height="30">
<Button x:Name="btnAccountSettings" Content="Account Settings" Style="{StaticResource LinkButton}" Width="100" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center"></Button>
</StackPanel>
<Separator Background="LightGray"/>
<StackPanel Height="30">
<Button x:Name="btnSwitchAccount" Content="Switch Account" Style="{StaticResource LinkButton}" Width="100" Margin="10,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center"></Button>
</StackPanel>
</StackPanel>
</Border>
</Popup>
<ContentPresenter Content="{TemplateBinding Property= ContentControl.Content}" />
</StackPanel>
</DataTemplate>
</Ribbon.HelpPaneContentTemplate>
<Ribbon.HelpPaneContent>
<RibbonButton x:Name="btnHelp" SmallImageSource="Images\help.png" />
</Ribbon.HelpPaneContent>

Related

WPF: Get control from ListView DataTemplate in Code Behind

I've created a ListView with a selfmade ItemTemplate, that is quite nested:
<ListView x:Name="QuestionListView" ItemsSource="{Binding QuestionList, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" Background="#afafaf" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" CornerRadius="15,0,0,15" BorderBrush="Gray" BorderThickness="0,0,1,0" Background="#676767" />
<Border Grid.Column="1" BorderBrush="Gray" BorderThickness="0,3,1,3" Background="#8f8f8f" />
<Border Grid.Column="2" CornerRadius="0,15,15,0" BorderThickness="1" BorderBrush="Gray" Background="#676767" />
<Label Content="{Binding ID}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="40" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontWeight="Bold" Foreground="Beige" />
<!--This is the TextEditor, I need in my Code behind-->
<Viewbox Grid.Column="1">
<avalonEdit:TextEditor xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit" Name="textEditor" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Width="600" FontSize="30" Background="Transparent" BorderBrush="Transparent" Foreground="Beige" PreviewLostKeyboardFocus="RichTextBox_PreviewLostKeyboardFocus" FontFamily="Consolas">
<i:Interaction.Behaviors>
<beh:AvalonEditBehaviour GiveMeTheText="{Binding TextQuestion, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</i:Interaction.Behaviors>
</avalonEdit:TextEditor>
</Viewbox>
<!--<TextBlock Grid.Column="1" IsHitTestVisible="False" FontSize="25" FontWeight="Bold" Foreground="LightGray" Text="Your question here" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding TextQuestion, Mode=TwoWay}" Value="">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>-->
<StackPanel Orientation="Horizontal" Grid.Column="2" HorizontalAlignment="Center">
<Button Margin="10,0,5,0" Width="40" Height="40" Background="Gray" Command="{Binding EditCommand}" MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave">
<Image Source="{Binding EditImage}" />
</Button>
<Button Margin="5,0,10,0" Width="40" Height="40" Background="Gray" Command="{Binding DeleteCommand}">
<Image Source="{Binding DeleteImage}" />
</Button>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
Now I want to get the TextEditor textEditor in my code behind, because I need it for the "Intellisense" window, I am customizing.
So I have this in my Code behind:
public partial class QuestionListUC : UserControl
{
TextEditor editor;
public QuestionListUC()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
var template = QuestionListView.Template;
editor = (TextEditor)template.FindName("textEditor", QuestionListView);
}
}
But the FindName-Method outputs nothing for me, the variable "editor" is null.
What am I doing wrong here?
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
Dispatcher.BeginInvoke(new Action(() => {
var template = QuestionListView.ItemTemplate;
editor = (TextEditor)template.FindName("textEditor",
QuestionListView);
}), DispatcherPriority.DataBind);
}
This should work
The most important change is
var template = QuestionListView.ItemTemplate;
The Dispatcher just delays the action until the data binding has been done, so the ItemTemplate should not be null
I managed to get a ViewBox around the Editor and then just use it's child. now I have the control in my CB

How to customize a PlaceholderText in a Listbox to have a specific color in UWP

I am working on a ListBox where I have using PlaceholderText property of TextBox. Here is my code for the ListBox. I am using A PopUp to implement the content
<Popup x:Name="ReasonCodePopUp" x:FieldModifier="Public" IsOpen="{Binding ShowFuelChangeReasonPopUp, Mode=TwoWay}"
Height="420" Width="1100" Grid.Row="0" Grid.RowSpan="2" IsLightDismissEnabled="True">
<Grid Height="397" Width="1100" >
<TextBlock Visibility="Collapsed" Name="txtFuelReason" Text="{x:Bind ViewModel.FuelPlanInfo.ExtraFuelReason,Mode=TwoWay}"/>
<ListBox Margin="20" Name="lstFuelReason" SelectionChanged="lstFuelReason_SelectionChanged"
Background="#414042" Height="420" Width="1100" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem IsEnabled="False" Margin="43.5,30.5,748.5,0">
<TextBlock Text="Reason Code" FontSize="32" FontFamily="Helvetica" FontWeight="Bold" Foreground="#ffffff" IsHitTestVisible="False" />
</ListBoxItem>
<ListBoxItem IsEnabled="False">
<Border Margin="43,0,57,0" BorderBrush="#979797" BorderThickness="0,0,0,1" Width="948"/>
</ListBoxItem>
<ListBoxItem>
<TextBlock Text="ATC" Margin="43,0,57,0" Foreground="#FFFFFF" FontSize="32" FontFamily="{ThemeResource Bold}" FontWeight="Normal" SelectionHighlightColor="Blue"></TextBlock>
</ListBoxItem>
<ListBoxItem IsEnabled="False">
<Border Margin="43,0,57,0" BorderBrush="#979797" BorderThickness="0,0,0,1" Width="948"/>
</ListBoxItem>
<ListBoxItem>
<TextBlock Text="Weather" Margin="43,0,57,0" Foreground="#FFFFFF" FontSize="32" FontFamily="{ThemeResource Bold}" FontWeight="Normal"></TextBlock>
</ListBoxItem>
<ListBoxItem IsEnabled="False" Margin="0">
<Border Margin="43,0,57,0" BorderBrush="#979797" BorderThickness="0,0,0,1" Width="948"/>
</ListBoxItem>
<ListBoxItem Height="50">
<TextBox PlaceholderText="Other" Margin="43.5,0,0,0" Tapped="FuelReasonOther_Tapped" TextChanged="TextBox_TextChanged" Foreground="#FF0078D7" FontSize="32" FontFamily="{ThemeResource Bold}" FontWeight="Normal" Style="{StaticResource TransparentTextBox}"/>
</ListBoxItem>
</ListBox>
</Grid>
</Popup>
I want to <TextBox PlaceholderText="Other"/>modify the foreground color of the "Other" as well as the text that is typed here to appear in Blue.
I know I need to play with the ContentTemplate but not able to do so.
If you override the TextControl defined brushes, you can change the colors to what you want without having to theme the whole TextBox control. I tested it with the following code, and it worked:
<TextBox PlaceholderText="Other" Margin="43.5,0,0,0" FontSize="32" FontWeight="Normal">
<TextBox.Resources>
<SolidColorBrush x:Key="TextControlPlaceholderForeground" Color="LightBlue"/>
<SolidColorBrush x:Key="TextControlPlaceholderForegroundFocused" Color="LightBlue" />
<SolidColorBrush x:Key="TextControlPlaceholderForegroundPointerOver" Color="LightBlue" />
<SolidColorBrush x:Key="TextControlForeground" Color="Blue" />
<SolidColorBrush x:Key="TextControlForegroundFocused" Color="Blue" />
<SolidColorBrush x:Key="TextControlForegroundPointerOver" Color="Blue" />
</TextBox.Resources>
</TextBox>
Note: I removed your bindings and event handlers to keep just the UI elements. But you should be able to add the TextBox.Resources to your TextBox and see it work.
The TextBox.Resources override the default brushes for TextControl (which is within the TextBox). These brush names are used by the control to draw in specific situations.
Let me know if this does the trick.

WPF TabItem HeaderTemplate

Sample code:
<TabControl>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal" Margin="5">
<Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
<TextBlock Text="Blue" Foreground="Blue" />
</StackPanel>
</TabItem.Header>
<Label Content="Content goes here..." />
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Text="Red" Foreground="Red" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal" Margin="5">
<Rectangle Fill="Red" width="20" height="16" />
</StackPanel>
</TabItem.Header>
</TabItem>
</TabControl>
As you can see, the TabItem Header is Always a stackpanel with different content:
<TabItem.Header>
<StackPanel Orientation="Horizontal" Margin="5">
</StackPanel>
</TabItem.Header>
How can you put this in a template so that I don't have duplicate stackpanel code?
Trying to do it like this:
<TabControl>
<TabControl.Resources>
<Style TargetType="TabItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="5">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}">
</ContentPresenter>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem>
<TabItem.Header>
<!-- ??? -->
<TextBlock Text="X" />
<TextBlock Text="Y" />
</TabItem.Header>
</TabControl>
results in:
"The property 'Header' is set more than once."
"The object 'Object' already has a child and cannot add 'TextBlock'. 'Object' can accept only one child."
The only thing the tree headers really have common is the Margin="5". In second and third tab the stackpanel is irrelavant, because it has only one child. You can achive it either by using HeaderTemplate or ItemContainerStyle:
<TabControl>
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="Padding" Value="5" />
</Style>
</TabControl.ItemContainerStyle>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
<TextBlock Text="Blue" Foreground="Blue" />
</StackPanel>
</TabItem.Header>
<Label Content="Content goes here..." />
</TabItem>
<TabItem>
<TabItem.Header>
<TextBlock Text="Red" Foreground="Red" />
</TabItem.Header>
</TabItem>
<TabItem>
<TabItem.Header>
<Rectangle Fill="Red" Width="20" Height="16" />
</TabItem.Header>
</TabItem>
</TabControl>
now you don't repeat anything.
You could also extract the properties of stackpanel to style to avoid repeating them:
<TabItem.Header>
<StackPanel Style="{StaticResource TabHeaderPanel}">
<Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
<TextBlock Text="Blue" Foreground="Blue" />
</StackPanel>
</TabItem.Header>
<TabItem.Header>
<StackPanel Style="{StaticResource TabHeaderPanel}">
<TextBlock Text="Red" Foreground="Red" />
</StackPanel>
</TabItem.Header>
<TabItem.Header>
<StackPanel Style="{StaticResource TabHeaderPanel}">
<Rectangle Fill="Red" width="20" height="16" />
</StackPanel>
</TabItem.Header>
If you want even more code reuse, you should consider MVVM-like approach:
<TabControl ItemsSource="{Binding Tabs}">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate DataType="local:TabViewModel">
<StackPanel Orientation="Horizontal" Margin="5">
<Image x:Name="Icon" Source="{Binding Icon, Converter={StaticResource UriToBitmapSourceConverter}}" />
<Rectangle x:Name="ColorRect" Height="16" Width="16" Fill="{Binding Color}" Visibility="Collapsed" />
<TextBlock Text="{Binding Title}" Foreground="{Binding Color}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Icon}" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed" />
<Setter TargetName="ColorRect" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
</TabControl>
if you can't use single DataTemplate for all headers, you can use HeaderTemplateSelector
I think HeaderTemplate will only be used if you are binding the Tab collection and generating them dynamically. This would work if you set your objects in a ViewModel (Header property is a collection of items that with implicit DataTemplates, could generate TextBlocks or Rectangles depending on their types).
Otherwise, you would either need to give your StackPanels common styling to make them all identical and save repetition, or set the first element of the TabItem.Header content to a custom control that derives from StackPanel.
I would choose the Style route myself, unless there is a really pressing need to remove even the StackPanel line from your XAML.

Column Headers Offset From Data in Wpf Datagrid

Good morning
I have a Wpf datagrid that is displaying an observable collection of a custom type
I group the data using a collection view source in XAML on two seperate properties, and I have styled the groups to display as expanders.
For clarity, as there is a lot of data I feel I have to use margins and spacing otherwise things look very cluttered.
My problem is that with two levels of hierarchical expanders the column data is now substantially offset from the column headers meaning that they do not properly line up.
I have tried several thing, like setting the margin of the column headers and the width (both actual and normal). However all of my attempts end up resizing the whole column so that the offset stays the same but the columns move.
so my question:
How can I change the visible width or offset of a column header to ensure that the headers line up with the data
Visual Studio 2012
Wpf
C#
DataGrid
EDIT This is what I mean
EDIT 2 - MY Xaml for Grouping
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Margin="5,10,5,5"
BorderBrush="{StaticResource BlackBrush}"
BorderThickness="1"
Header="{Binding Name}"
IsExpanded="True">
<Expander.Template>
<!-- The basic expander -->
<ControlTemplate TargetType="{x:Type Expander}">
<!-- Put a border around the expander -->
<Border Background="{Binding Path=Name,
Converter={StaticResource ColourConverter}}"
BorderBrush="{StaticResource GreyBrush}"
BorderThickness="2"
CornerRadius="3">
<!-- Use a dock panel so that the toggle button is docked to the top and the content is docked to the bottom -->
<DockPanel Margin="0">
<!-- Add the toggle button -->
<ToggleButton x:Name="ExpanderButton"
Margin="0"
Content="{TemplateBinding Header}"
DockPanel.Dock="Top"
FontSize="14"
FontWeight="Bold"
Foreground="{StaticResource BlackBrush}"
IsChecked="{Binding Path=IsExpanded,
RelativeSource={RelativeSource TemplatedParent}}"
OverridesDefaultStyle="True"
Template="{StaticResource AnimatedExpanderButton}" />
<ContentPresenter x:Name="ExpanderContent"
Margin="5"
ContentSource="Content"
DockPanel.Dock="Bottom"
Visibility="{Binding ElementName=ExpanderButton,
Path=IsChecked,
Converter={StaticResource VisibilityConverter}}" />
</DockPanel>
</Border>
</ControlTemplate>
</Expander.Template>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
<!-- Style for groups under the top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0,0,0,5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander Margin="5"
Background="{Binding Path=Name,
Converter={StaticResource ColourConverter}}"
IsExpanded="True"
Visibility="{Binding Items[0].IsSelectedInSidebar,
Converter={StaticResource VisibilityConverter}}">
<Expander.Template>
<!-- The basic expander -->
<ControlTemplate TargetType="{x:Type Expander}">
<!-- Put a border around the expander -->
<Border Background="{Binding Path=Name,
Converter={StaticResource ColourConverter}}"
BorderBrush="{StaticResource GreyBrush}"
BorderThickness="2"
CornerRadius="3">
<!-- Use a dock panel so that the toggle button is docked to the top and the content is docked to the bottom -->
<DockPanel Margin="0">
<!-- Add the toggle button -->
<ToggleButton x:Name="ExpanderButton"
Content="{Binding Path=Name}"
DockPanel.Dock="Top"
FontSize="12"
IsChecked="{Binding Path=IsExpanded,
RelativeSource={RelativeSource TemplatedParent}}"
OverridesDefaultStyle="True"
Template="{StaticResource AnimatedExpanderButton}" />
<ContentPresenter x:Name="ExpanderContent"
Margin="5"
ContentSource="Content"
DockPanel.Dock="Bottom"
Visibility="{Binding ElementName=ExpanderButton,
Path=IsChecked,
Converter={StaticResource VisibilityConverter}}" />
</DockPanel>
</Border>
</ControlTemplate>
</Expander.Template>
<Expander.Content>
<Border BorderBrush="{StaticResource BlackBrush}" BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ItemsPresenter Grid.Row="0" Margin="0" />
<Border Grid.Row="1"
Margin="0,10,0,0"
BorderBrush="{StaticResource BlackBrush}"
BorderThickness="0,1,0,0"
Visibility="{Binding Data.SettingRepository.MainDataSummaryVisible,
Source={StaticResource BindingProxy},
Converter={StaticResource VisibilityConverter}}">
<Grid Background="{StaticResource WhiteBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.ColumnSpan="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Margin="5"
FontWeight="Bold"
Text="{Binding Path=Items[0].Option1Title}"
Visibility="{Binding Data.SettingRepository.MainDataShowSampleOptions,
Source={StaticResource BindingProxy},
Converter={StaticResource VisibilityConverter}}" />
<TextBlock Grid.Column="1"
Margin="5"
Text="{Binding Path=Items[0].Option1Data,
Mode=OneWay}"
Visibility="{Binding Data.SettingRepository.MainDataShowSampleOptions,
Source={StaticResource BindingProxy},
Converter={StaticResource VisibilityConverter}}" />
<TextBlock Grid.Column="2"
Margin="5"
FontWeight="Bold"
Text="{Binding Path=Items[0].Option2Title}"
Visibility="{Binding Data.SettingRepository.MainDataShowSampleOptions,
Source={StaticResource BindingProxy},
Converter={StaticResource VisibilityConverter}}" />
<TextBlock Grid.Column="3"
Margin="5"
Text="{Binding Path=Items[0].Option2Data,
Mode=OneWay}"
Visibility="{Binding Data.SettingRepository.MainDataShowSampleOptions,
Source={StaticResource BindingProxy},
Converter={StaticResource VisibilityConverter}}" />
<TextBlock Grid.Column="4"
Margin="5"
FontWeight="Bold"
Text="{Binding Path=Items[0].Option3Title}"
Visibility="{Binding Data.SettingRepository.MainDataShowSampleOptions,
Source={StaticResource BindingProxy},
Converter={StaticResource VisibilityConverter}}" />
<TextBlock Grid.Column="5"
Margin="5"
Text="{Binding Path=Items[0].Option3Data,
Mode=OneWay}" />
<TextBlock Grid.Column="6"
Margin="5"
FontWeight="Bold"
Text="{Binding Path=Items[0].Option4Title}"
Visibility="{Binding Data.SettingRepository.MainDataShowSampleOptions,
Source={StaticResource BindingProxy},
Converter={StaticResource VisibilityConverter}}" />
<TextBlock Grid.Column="7"
Margin="5"
Text="{Binding Path=Items[0].Option4Data,
Mode=OneWay}"
Visibility="{Binding Data.SettingRepository.MainDataShowSampleOptions,
Source={StaticResource BindingProxy},
Converter={StaticResource VisibilityConverter}}" />
<TextBlock Grid.Column="8"
Margin="5"
FontWeight="Bold"
Text="{x:Static languages:Strings.SampleIsAnnealedColumnHeader}" />
<CheckBox Grid.Column="9"
Margin="3,5,5,5"
IsChecked="{Binding Path=Items[0].SampleIsAnnealed,
Mode=OneWay}"
IsHitTestVisible="False"
Style="{StaticResource FandFCheckBox}" />
</Grid>
<!-- The mean Match temperature -->
<TextBlock Grid.Row="1"
Grid.Column="0"
Margin="5"
FontWeight="Bold"
Text="{x:Static languages:Strings.MeanSampleMatchTemperatureTitle}" />
<TextBlock Grid.Row="1"
Grid.Column="1"
Margin="5"
Text="{Binding Path=Items[0].SampleMeanMatchTemperature,
Mode=OneWay,
StringFormat=\{0:N2\}}" />
<!-- The match temperature range -->
<TextBlock Grid.Row="1"
Grid.Column="2"
Margin="5"
FontWeight="Bold"
Text="{x:Static languages:Strings.SampleTemperatureRangeTitle}" />
<TextBlock Grid.Row="1"
Grid.Column="3"
Margin="5"
Text="{Binding Path=Items[0].SampleMatchTemperatureRange}" />
<!-- The match temperature standard deviation -->
<TextBlock Grid.Row="1"
Grid.Column="4"
Margin="5"
FontWeight="Bold"
Text="{x:Static languages:Strings.SampleTemperatureStandardDeviationTitle}" />
<TextBlock Grid.Row="1"
Grid.Column="5"
Margin="5"
Text="{Binding Path=Items[0].SampleMatchTemperatureStandardDeviation,
Mode=OneWay,
StringFormat=\{0:N3\}}" />
<!-- The mean refractive index -->
<TextBlock Grid.Row="2"
Grid.Column="0"
Margin="5"
FontWeight="Bold"
Text="{x:Static languages:Strings.SampleMeanRefractiveIndexTitle}" />
<TextBlock Grid.Row="2"
Grid.Column="1"
Margin="5"
Text="{Binding Path=Items[0].SampleMeanRefractiveIndex,
Mode=OneWay,
StringFormat=\{0:N5\}}" />
<!-- The refractive index range -->
<TextBlock Grid.Row="2"
Grid.Column="2"
Margin="5"
FontWeight="Bold"
Text="{x:Static languages:Strings.SampleRIRangeTitle}" />
<TextBlock Grid.Row="2"
Grid.Column="3"
Margin="5"
Text="{Binding Path=Items[0].SampleRefractiveIndexRange}" />
<!-- The refractive index standard deviation -->
<TextBlock Grid.Row="2"
Grid.Column="4"
Margin="5"
FontWeight="Bold"
Text="{x:Static languages:Strings.SampleRIStandardDeviationTitle}" />
<TextBlock Grid.Row="2"
Grid.Column="5"
Margin="5"
Text="{Binding Path=Items[0].SampleRefractiveIndexStandardDeviation,
Mode=OneWay,
StringFormat=\{0:N7\}}" />
</Grid>
</Border>
</Grid>
</Border>
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
You can set the ColumnHeaderStyle and there set a RenderTransform that moves the headers to the right.
<DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="RenderTransform">
<Setter.Value>
//change the X value accordingly
<TranslateTransform X="100"></TranslateTransform>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
EDIT 2:
As you mentioned, doing this will result in a small gap. To remove it you should set the left margin of the first column to a negative value, which stretches the header of this column to the left. You can do it like this:
<DataGridTemplateColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
//change the margin accordingly
<Setter Property="Margin" Value="-100 0 0 0" />
<Setter Property="RenderTransform">
<Setter.Value>
//change the X value accordingly
<TranslateTransform X="100"></TranslateTransform>
</Setter.Value>
</Setter>
</Style>
</DataGridTemplateColumn.HeaderStyle>
You have to set the RenderTransform here again, because this style overwrites the general ColumnHeaderStyle. To remove duplication you can add the render transfrom as a resource.
EDIT:
I just saw that you have a few margins on your Expanders and ContentPresenters. If you change them so that you have 0 margin to the left, it would align the content more to the left and reduce the alignment difference.
You would then need less offset on the RenderTransform.
Some examples of your code to illustrate what I mean:
<Expander Margin="5,10,5,5"
<ContentPresenter x:Name="ExpanderContent" Margin="5"
If you change it to
<Expander Margin="0,10,5,5"
<ContentPresenter x:Name="ExpanderContent" Margin="0 5 5 5"
the columns move more to the left.

How to use wpf expender alignment

I am trying to create a WPF window to have a simple expander to extend the datagrid when the user clicks on the More expander button. When the user wants to hide the datagrid, user just has to clik on the Less expander button.
I am also using dock panel to separate header, left, right and footer.
The problems are :
I want to have the less button to be in center before the user
click on the more expander button. When the user clicks on the more
expander button, the less button will be pushed to the left, to show
the datagrid on the right.
How do I change the name of the expander when its closed and
open. Can I do it at the xaml level?
Below is the xaml code:
<Window x:Class="M.SalesWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SalesWindow" Height="300" Width="300">
<DockPanel>
<StackPanel DockPanel.Dock="Top">
<Label FontSize="28" Content="Sales">
</Label>
</StackPanel>
<StackPanel DockPanel.Dock="Left" Width="auto" HorizontalAlignment="Center">
<Label FontSize="15" Content="Enter Amount" Height="26" Width="168" />
<Separator Width="168" />
</StackPanel>
<StackPanel DockPanel.Dock="Right">
<Expander ExpandDirection="Left" HorizontalAlignment="Right" VerticalAlignment="Stretch">
<Expander.Header>
<TextBlock Text="More">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Expander.Header>
<Expander.Content>
<StackPanel>
<DataGrid ItemsSource="{Binding Products}">
</DataGrid>
</StackPanel>
</Expander.Content>
</Expander>
</StackPanel>
</DockPanel>
</Window>
Thank you.
Replace your code with the below code and see the magic. This will also solve your problem of alignment as per your requirement. I have removed the DockPanel as you can achieve the similar result with this piece of code.
<StackPanel>
<StackPanel>
<Label FontSize="28" Content="Sales">
</Label>
</StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" HorizontalAlignment="Center">
<Label FontSize="15" Content="Enter Amount" Height="26" Width="168" />
<Separator Width="168" />
</StackPanel>
<Expander Grid.Column="1" ExpandDirection="Left" HorizontalAlignment="Right" VerticalAlignment="Stretch">
<Expander.Style>
<Style TargetType="Expander">
<Setter Property="IsExpanded" Value="False" />
<Setter Property="Header">
<Setter.Value>
<TextBlock Text="Less">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsExpanded,RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Header">
<Setter.Value>
<TextBlock Text="More">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
<Expander.Content>
<StackPanel>
<DataGrid ItemsSource="{Binding Products}">
</DataGrid>
</StackPanel>
</Expander.Content>
</Expander>
</Grid>
</StackPanel>
The trick lies under the following lines of code.
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

Categories

Resources