Bind an Inner Label Text to the component ToolTip - c#

I'm actually overriding the ControlTemplate of the default WPF TextBox and i'd like to add a Title to it. The idea here is that the title will be displayed as a placeholder when the TextBox is empty and not focused, and will slide up at the top to become the title in the other cases.
As the TextBox don't have a PlaceHolder or a Title property, i thought i could bind my title TextBlock to the ToolTip in order to be able to do this:
<TextBox ToolTip="MyTextBoxTitle"/>
My template looks like this :
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="14"/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock x:Name="Title" Text="{Binding Path=ToolTip}" Margin="8,14,0,0" Grid.Row="0" Grid.RowSpan="2" Foreground="{StaticResource TextBox.Static.Border}"></TextBlock>
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Grid.Row="1"/>
<Rectangle x:Name="UnfocusedUnderLine" Fill="{StaticResource TextBox.Static.Border}" Height="6" Margin="0,1,0,0" Grid.Row="2"/>
<Rectangle x:Name="UnderLine" Fill="{StaticResource TextBox.Focus.Border}" Height="6" Margin="0,1,0,0" Grid.Row="2" Width="0"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
...
</ControlTemplate.Triggers>
</ControlTemplate>
But my Binding on the ToolTip doesn't work, and i can't manage to find a way to make it work, do you know how to do this ?

Use:
Text="{TemplateBinding ToolTip}"
You need a binding whose source is not the DataContext but the templated element which is TextBox in your case.

Related

TabControl Border is not hidden when adding the new button(add button) in tabpanel in wpf

In tab control i have to add + button to tab item like in screenshot. I added the plus button to tab panel, when i run the program and selecting the tab item the tab control border is not hidden like normal tab control. please check the attached screenshot for clarity of my question.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid
x:Name="templateRoot"
ClipToBounds="true"
KeyboardNavigation.TabNavigation="Local"
SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0" />
<ColumnDefinition x:Name="ColumnDefinition1" Width="0" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto" />
<RowDefinition x:Name="RowDefinition1" Height="*" />
</Grid.RowDefinitions>
<StackPanel
x:Name="headerPanel"
Grid.Row="0"
Grid.Column="0"
Orientation="Horizontal">
<TabPanel
x:Name="_HeaderPanel"
Panel.ZIndex="1"
IsItemsHost="true"
KeyboardNavigation.TabIndex="1" />
<Button
x:Name="addButton"
Width="50"
Height="30"
Background="LightGray"
BorderBrush="LightGray"
BorderThickness="1,0,0,0"
Command="{Binding ChartAddButton_Click}"
Content="+" />
</StackPanel>
<Border
x:Name="contentPanel"
Grid.Row="1"
Grid.Column="0"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="2"
KeyboardNavigation.TabNavigation="Local">
<ContentPresenter
x:Name="PART_SelectedContentHost"
Margin="{TemplateBinding Padding}"
ContentSource="SelectedContent"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</Grid>
By adding the plus button to tab panel this will occurs. How to fix this. Please give your suggestion.
Please refer the updated screenshot
I assume you're referring to the dotted lines. That's not the border that's being displayed, I think that's the default FocusVisualStyle of the Button.
Try setting,
FocusVisualStyle = "{x:null}"
on the Button.

WPF charting toolkit Legend location

How to change the location of legend in WPF Charting Toolkit?
I'm using Line Series and the legend appears at the right side reducing the width of charting area.
I'd like to locate the legend for example at the right top corner of chart.
How to do it?
You need to modify the ControlTemplate a bit:
<chartingToolkit:Chart Title="...">
<chartingToolkit:Chart.Template>
<ControlTemplate TargetType="{x:Type chartingToolkit:Chart}"
xmlns:visualizationToolkit="clr-namespace:System.Windows.Controls.DataVisualization;assembly=System.Windows.Controls.DataVisualization.Toolkit"
xmlns:Primitives="clr-namespace:System.Windows.Controls.DataVisualization.Charting.Primitives;assembly=System.Windows.Controls.DataVisualization.Toolkit" >
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<visualizationToolkit:Title Content="{TemplateBinding Title}" Style="{TemplateBinding TitleStyle}"/>
<Grid Grid.Row="1">
<Primitives:EdgePanel x:Name="ChartArea" Style="{TemplateBinding ChartAreaStyle}">
<Grid Style="{TemplateBinding PlotAreaStyle}" Panel.ZIndex="-1"/>
<Border BorderBrush="#FF919191" BorderThickness="1" Panel.ZIndex="10"/>
</Primitives:EdgePanel>
<visualizationToolkit:Legend x:Name="Legend"
Style="{TemplateBinding LegendStyle}"
Title="{TemplateBinding LegendTitle}"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Margin="0 2 2 0"/>
</Grid>
</Grid>
</Border>
</ControlTemplate>
</chartingToolkit:Chart.Template>
</chartingToolkit:Chart>

how to dynamically change rectangle color in Expander?

I have an Expander in which i have Rectangle with color. i want to change dynamically after some functionality. how to change it on run time ?
<Windows.Resources>
<ControlTemplate x:Key="SimpleExpanderButtonTemp"
TargetType="{x:Type ToggleButton}">
<Border x:Name="ExpanderButtonBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="ExpandRect" Fill="Transparent"
Grid.ColumnSpan="2"/>
<Ellipse Name="Circle"
Grid.Column="0"
Stroke="DarkGray"
Width="20"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
</Grid>
</Border>
</>
</Windows.Resources>
Anyone help :
If you want to change this in code behind, I would bind to a brush resource using {DynamicResource key} binding. Your code behind can then update that resource to whatever you want where ever you need it to.
this.Resource["RectangleBrush"] = new SolidColorBrush(Colors.Red);
If you want to control it via data in a view model, use a datatrigger. Link to similar answer
If you're basing it on multiple bindings - you can use a multibinding with a converter : Tutorial here
<Rectangle Fill="Transparent" x:Name="ExpanderButtonRectangle"
Grid.ColumnSpan="2"/>
ExpanderButtonRectangle.Fill = new SolidColorBrush(Colors.Red);

How do you reproduce the text displayed in a TreeViewItem while using a ControlTemplate?

I am attempting to modify a TreeView to display the TreeViewItem values above and below their child items, such that:
foo
|bar
||baz
|biz
would become
foo
|bar
||baz
| baz
|bar
|biz
biz
foo
A trimmed representation of the current control template is provided below, provided with no guarantee that this snippet compiles:
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="19"
Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander"
IsChecked="{Binding Path=IsExpanded,
RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"/>
<Border Name="Bd"
Grid.Column="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
<ItemsPresenter x:Name="ItemsHost"
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2"/>
<TextBlock Text="Some Binding Goes Here"
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"/>
</Grid>
</ControlTemplate>
The repeated entries would not have children, it would just be the display value. Thus far I can modify the TreeView ContainerStyle using a ControlTemplate to insert a TextBlock at the appropriate place in the visual tree. What data binding should be used in order to fetch the appropriate display value?
Why not use a ContentPresenter again?
<ContentPresenter ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"/>

How to change appearance of TabItems in a scrolling WPF TabControl?

I have a scrolling TabControl, using a ScrollViewer and StackPanel (with the StackPanel set as IsItemsHost="true"). To begin with, I am working from a solution originally outlined here - Creating Scrolling Tabs Using WPF's TabControl . At the moment it has broken links (Edit: I have tracked down one instance of his code in a forum here - How to prevent TabControl from doing multi rows?), so here is the xaml for the TabControl (does not require any further code):
<TabControl x:Name="TabControl2" Height="Auto" TabStripPlacement="Bottom" VerticalAlignment="Bottom" Template="{DynamicResource TabControlControlTemplate1}" IsSynchronizedWithCurrentItem="True">
<TabControl.Resources>
<Style x:Key="TabScrollerRepeatButtonStyle" TargetType="{x:Type RepeatButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" Margin="1,0">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding ContentControl.Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="TabControlControlTemplate1" TargetType="{x:Type TabControl}">
<Grid x:Name="Grid" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="1" Grid.Column="0" x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,1,1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Border Background="{TemplateBinding Background}" x:Name="Border1">
<ContentPresenter DataContext="{x:Null}" Margin="{TemplateBinding Padding}" x:Name="PART_SelectedContentHost" Content="{TemplateBinding SelectedContent}" ContentTemplate="{TemplateBinding SelectedContentTemplate}" ContentTemplateSelector="{TemplateBinding SelectedContentTemplateSelector}" ContentSource="SelectedContent"/>
</Border>
</Border>
</Border>
<ScrollViewer x:Name="HeaderPanel" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<ScrollViewer.Style>
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Margin="0,0,0,0" Grid.Row="0" Grid.Column="0" x:Name="HeaderPanel">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<RepeatButton Grid.Column="1" Content="<" Command="ScrollBar.LineLeftCommand" Style="{DynamicResource TabScrollerRepeatButtonStyle}" Visibility="{Binding Path=ComputedHorizontalScrollBarVisibility, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
<ScrollContentPresenter Grid.Column="2" Content="{TemplateBinding ScrollViewer.Content}" />
<RepeatButton Grid.Column="3" Content=">" Command="ScrollBar.LineRightCommand" Style="{DynamicResource TabScrollerRepeatButtonStyle}" Visibility="{Binding Path=ComputedHorizontalScrollBarVisibility, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ScrollViewer.Style>
<StackPanel IsItemsHost="true" Orientation="Horizontal" Background="{x:Null}" KeyboardNavigation.TabIndex="1"/>
</ScrollViewer>
</Grid>
</ControlTemplate>
</TabControl.Resources>
<TabItem x:Name="TabItem1" Header="TabItem1"/>
<TabItem x:Name="TabItem2" Header="TabItem2"/>
</TabControl>
How might I adjust the appearance of each TabItem? For instance, I would like to place a TextBox and TextBlock inside each TabItem, with the help of a StackPanel, so that I can have renameable tabs (collapsing one or the other as appropriate). I might also want to add a close button on each tab. Ordinarily, I would use something like the following:
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Name="panel" Orientation="Horizontal">
<TextBox Name="editHeader" Text="{Binding Header}" MaxWidth="250"/>
<TextBlock Name="textHeader" Text="{Binding Header}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
.. but this is having no effect at all. Any ideas would be appreciated. Thanks.
Edit: I am still trying to figure this out. Is it possible that the solution could involve ContentPresenter and/or SelectedContentTemplate?
Edit 2: (this doesn't add value to my question) I really, really wish WPF included something of this sort out of the box. I am baffled by TabControl's default behavior, and by the fact that there is no scrollable TabControl (nor simple solution for attaining one) after some years.
Hey guesser. I've done something similar, I based mine off of this series though
http://www.blogs.intuidev.com/post/2010/post/2010/01/25/TabControlStyling_PartOne.aspx
The method used is to simply style the tabitems template. eg:
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<!-- your custom template goes here -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
Unforunately this method means you will have to completely redefine the way the tab items look and behave. But the provided link gives good examples on how achieve this.
Hope it helps.
Just a thought,
have you tried just adding the text block to the TabItem.Header? If you do this instead of a template it might work. Has for me in the past
I think I've got it (though still crossing fingers a bit -- I haven't yet dealt with Visibility of the TextBlock vs TextBox for renaming).
It is similar to Val's solution in that I'm working in TabControl.Resources on its TabItem, but the Property concerned is HeaderTemplate and I just override the ContentPresenter in a DataTemplate. (measures to avoid replacing\destroying a lot of good behavior that comes for free with the TabControl)
<TabControl.Resources>
<Style TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<ContentPresenter>
<ContentPresenter.Content>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{TemplateBinding Content}"/>
<TextBox Text="{TemplateBinding Content}"/>
</StackPanel>
</ContentPresenter.Content>
</ContentPresenter>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
I'm somewhat of a WPF newb, so this is basically a result of persistent experimentation with what I could find Googling. For those interested, this link (on StackOverflow) helped me most in the end - WPF TabItem Header Styling

Categories