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.
Related
I have a list of items which a user can select and I would like to add an explanation text. So far I have this code
<TabItem Name="TabItem02" Header="">
<ListBox Name="listBox01" VerticalAlignment="Stretch" SelectionMode="Multiple" HorizontalAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectedValuePath="Content">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<CheckBox Margin="5,2" IsChecked="{TemplateBinding IsSelected}" Grid.Column="0" VerticalAlignment="Top">
<ContentPresenter VerticalAlignment="Center">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<TextBlock Text="{TemplateBinding Content}" TextWrapping="Wrap" />
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</CheckBox>
<Expander Header="Explanation" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" FlowDirection="RightToLeft">
<TextBlock TextWrapping="Wrap" FlowDirection="LeftToRight"/>
</Expander>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBoxItem Name="List1Item01" IsEnabled="False"/>
<ListBoxItem Name="List1Item02" IsEnabled="False"/>
<ListBoxItem Name="List1Item03" IsEnabled="False"/>
<ListBoxItem Name="List1Item04" IsEnabled="False"/>
<ListBoxItem Name="List1Item05" IsEnabled="False"/>
</ListBox>
</TabItem>
And at the moment I am changing the content of each ListBox through a ressourcefile with this code-behind
foreach (ListBox listBox in ListBoxes)
{
foreach (ListBoxItem item in listBox.Items) item.Content = resourceManager.GetString(item.Name);
}
I would like to change the text of the second TextBlock (the one in the Expander) according to the ListBoxItem it belongs to as easy as the ListBox content itself through the ressourcefile. I would prefer not to create a separate Expander + TextBlock for each ListBoxItem with a separate name.
So if anyone has a solution for my problem, I would really appreciate that.
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.
I'm trying to have my TabItem Collapsed or Hidden. I've tried many solutions and none have worked. The Tab Item still remains
If I may get some guidance please.
one solution I've Tried
<TabItem >
<TabItem.Header>
<StackPanel Visibility="Collapsed">
<TextBlock Text="Transactions" />
</StackPanel>
</TabItem.Header>
<panes:Transactions />
</TabItem>
private Visibility statementVisibility;
public Visibility StatementVisibility { get { return statementVisibility; } set { statementVisibility = value; OnPropertyChanged("StatementVisibillity"); } }
Changed "Collapsed" to StatementVisibility and still nothing.
UPDATE:
After poking around, I've found a link to the TabItems that I think may play a factor.
Generic.xaml
<ListBox Foreground="#FFF" Name="TabSelector" Grid.Row="2" ItemsSource="{Binding Path=Items, ElementName=Tabs}">
<ListBox.Background>
<SolidColorBrush Color="#333"/>
</ListBox.Background>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0 0 0 1" SnapsToDevicePixels="False" BorderBrush="#22000000">
<TextBlock FontSize="14" Height="30" VerticalAlignment="Center" Margin="0" Padding="6" Text="{Binding Header}"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Border Grid.Column="1" Grid.Row="2" Background="White" BorderThickness="0">
<ContentPresenter Name="PART_TabbedFormPresenter"
Content="{Binding TabbedForm, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type shell:ActionScreenControl}}}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type shell:ActionScreenControl}}}">
<ContentPresenter.Resources>
<Style TargetType="TabItem">
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
Loanview.xaml.cs
<shell:ActionScreenControl.TabbedForm>
<TabControl>
<TabItem......./>
<TabItem......./>
<TabItem >
<TabItem.Header>
<StackPanel Visibility="Collapsed">
<TextBlock Text="Transactions" />
</StackPanel>
</TabItem.Header>
<panes:Transactions />
</TabItem>
</TabControl>
</shell:ActionScreenControl.TabbedForm>
Try setting the Visibility property on the actual TabItem itself:
<TabControl>
<TabItem Visibility="Collapsed">
<TabItem.Header>
<StackPanel>
<TextBlock Text="Transactions" />
</StackPanel>
</TabItem.Header>
<panes:Transactions />
</TabItem>
</TabControl>
Ahhhh... you want to data bind. Then you'll need to use a BooleanToVisibilityConverter element and a bool property:
<TabItem Visibility="{Binding YourBoolProperty,
Converter={StaticResource BooleanToVisibilityConverter}">
<TabItem.Header>
<StackPanel>
<TextBlock Text="Transactions" />
</StackPanel>
</TabItem.Header>
<panes:Transactions />
</TabItem>
See the IValueConverter Interface page on MSDN to see how to use a converter.
This is from production code and it works
<TabItem Visibility="{Binding Path=MyGabeLib.CurUser.DisplayTSQL, Converter={StaticResource bvc}}">
<TabItem.Header>
<TextBlock Style="{StaticResource HeaderTextBlockStyle}">TSQL</TextBlock>
</TabItem.Header>
<ScrollViewer VerticalScrollBarVisibility="Visible">
<TextBox Text="{Binding Path=MyGabeLib.Search.CurrentTSQL, Mode=OneWay}" IsReadOnly="True"
TextWrapping="Wrap" FontFamily="Courier New"/>
</ScrollViewer>
</TabItem>
If you are returning Visibility then you would not need a converter
Try with a simple TextBlock - I suspect you have a datacontext problem
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>
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>