Can't access the Text property of a TextBlock in a ControlTemplate - c#

I'm trying to data bind a property to a Label and change its color and text in response to the value of the bound property. I'm using a ControlTemplate to change the color and Text because changing the Content of a Label in response to DataTriggers didn't work (the text never appeared).
So, using a ControlTemplate works when defining it inline on the Label, but does not seem to work when defining the template as a resource.
The code below is a simpler example to demonstrate the problem.
This is what I have so far:
<ResourceDictionary>
<ControlTemplate x:Key="baseTemplate" TargetType="{x:Type Label}">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="24"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="InnerTextBlock" Grid.Column="1"
Text="{TemplateBinding Label.Content}" <!-- An attempt to tie the Text here to the Label's Content property -->
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
/>
</Grid>
</ControlTemplate>
<Style x:Key="availableLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Background" Value="#FF567E4A"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Content" Value="Available"/>
<Setter Property="Template" Value="{StaticResource baseTemplate}"/>
</Style>
</ResourceDictionary>
<Label x:Name="StatusLabel"
Style="{StaticResource availableLabelStyle}"
Grid.Column="1"
HorizontalAlignment="Left"
Margin="111,71,0,0"
VerticalAlignment="Top" Width="124"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Height="18"
Padding="2"
/>
The problem is that the Content property in the Setter for the 'availableLabelStyle' does not seem to work. No text appears when this style is applied to a Label.
Is there a better way to do the same thing here AND get the text to appear in the Label?
Thanks in advance for any help on this.

The code you have is working. Here is my complete example:
<Window x:Class="WPFTestApp2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="baseTemplate" TargetType="{x:Type Label}">
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="24"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" Text="{TemplateBinding Label.Content}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"/>
</Grid>
</ControlTemplate>
<Style x:Key="availableLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Background" Value="#FF567E4A"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Content" Value="Available"/>
<Setter Property="Template" Value="{StaticResource baseTemplate}"/>
</Style>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Label x:Name="StatusLabel" Style="{StaticResource availableLabelStyle}"
Grid.Column="1"
HorizontalAlignment="Left"
Margin="111,71,0,0"
VerticalAlignment="Top" Width="124"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Height="18"
Padding="2"/>
</Grid>
</Window>
Which produces the following output:

Another way to do this is to use ContentPresenter instead of TextBlock. You can still add all of your additional properties to it (at least the ones you have shown), and it would allow displaying content other than text.

Related

Wpf drop event not firing

I have a user control simulating water mark text box.
I need to allow drop text files on the user control.
The PreviewDragEnter event works fine. This is the event where i want to verify that the file that been drag is actually a text file.
The problem is that the drop event never fires.
I want to catch the event when the user release the mouse button and decide to drop the file into the user control.
I think it got something to do with the multiple controls inside the user control and the hierarchy.
I really don't care which control will fire the drop event as long as it actually fire.
This is the xaml (the control i want to target the drop event is name 'txt')
<UserControl x:Class="CrumbSearch.CustomControls.package_watermark"
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"
Height="45" Width="Auto"
FontFamily="B Yekan"
AllowDrop="true"
Grid.IsSharedSizeScope="True"
xmlns:wpfwatermarktextbox="clr-namespace:WPFWaterMarkTextBox;assembly=WPFWaterMarkTextBox">
<FrameworkElement.Resources>
<ResourceDictionary>
<FontFamily x:Key="simple_line_icon">/fonts/Simple-Line-Icons.ttf#simple-line-icons</FontFamily>
<Style x:Key="SimpleTextBox" TargetType="{x:Type TextBox}">
<Setter Property="AllowDrop" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border Name="border" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer Name="PART_ContentHost" Focusable="False" Margin="2,10,0,0"
AllowDrop="True"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsFocused" Value="True">
<Setter TargetName="border" Property="Border.BorderBrush" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="SimplePasswordBox" TargetType="{x:Type PasswordBox}">
<Setter Property="AllowDrop" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Name="border" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ScrollViewer Name="PART_ContentHost"
Focusable="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsFocused" Value="True">
<Setter TargetName="border" Property="Border.BorderBrush" Value="#00000000" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</FrameworkElement.Resources>
<Border Name="border" BorderThickness="0.5" CornerRadius="4" MouseEnter="border_MouseEnter"
MouseLeave="border_MouseLeave">
<FrameworkElement.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="BorderBrush" Value="White" />
<Setter Property="AllowDrop" Value="true" />
</Style>
</FrameworkElement.Style>
<Grid Name="MainGrid" PreviewMouseLeftButtonDown="MainGrid_PreviewMouseLeftButtonDown"
LostFocus="MainGrid_LostFocus">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Name="lbl2" Padding="5,0" FontSize="10" Content="Name"
Margin="0,5,0,0"
HorizontalAlignment="Left" Foreground="White" FlowDirection="LeftToRight"
VerticalAlignment="Top" Height="13" Grid.IsSharedSizeScope="True"
Opacity="0" Grid.Column="1" Background="{x:Null}" />
<TextBlock Name="lbl" Text="WaterMark" HorizontalAlignment="Left"
Foreground="#0EE7EC" FontSize="12"
Padding="5,5,5,0" FlowDirection="LeftToRight" FontFamily="Andalus"
TextWrapping="WrapWithOverflow" FontStyle="Italic"
Opacity="0.7" Grid.Column="1"
VerticalAlignment="Center" Background="{x:Null}" />
<TextBox Name="txt" Style="{DynamicResource SimpleTextBox}" FlowDirection="LeftToRight"
AllowDrop="true" Background="{x:Null}"
PreviewDragEnter="txt_PreviewDragEnter"
PreviewDrop="txt_PreviewDrop" Drop="txt_Drop"
TextWrapping="NoWrap" VerticalContentAlignment="Center" FontSize="14"
VerticalScrollBarVisibility="Disabled" MaxLines="1" FontWeight="Medium" Grid.Column="1"
BorderBrush="{x:Null}" TextChanged="TextBox_TextChanged" Foreground="White"
PreviewGotKeyboardFocus="txt_PreviewGotKeyboardFocus"
PreviewLostKeyboardFocus="txt_PreviewLostKeyboardFocus" />
<PasswordBox Name="pass" Style="{DynamicResource SimplePasswordBox}" FontSize="14"
VerticalContentAlignment="Center"
ScrollViewer.VerticalScrollBarVisibility="Disabled" Grid.Column="1"
Visibility="Collapsed" BorderBrush="{x:Null}"
Background="{x:Null}" PasswordChanged="PasswordBox_PasswordChanged" />
<Label Name="LblIcon" Padding="0" FontFamily="{DynamicResource simple_line_icon}"
VerticalContentAlignment="Center" HorizontalContentAlignment="Center"
Foreground="#FF6A6A6A" FontSize="14" Background="{x:Null}" />
</Grid>
</Border>
</UserControl>
Found the answer here:
https://peteohanlon.wordpress.com/2009/09/28/textbox-dragdrop-in-wpf/
Apparently, Drag Drop into a TextBox in WPF doesn’t actually work. When you attempt to drag and drop an item into a TextBox, it refuses to cooperate and leaves the mouse cursor as the Drop denied cursor and you can’t drop into the field. (Incidentally, this behaviour also applies to RichTextBox and FlowDocument controls). The reason that you can’t drop into these fields, even if you set AllowDrop to true, is that these particular controls mark drag and drop events as handled, preventing you from handling them yourself.

Switching Focus from Grid/TextBlock to TextBox

I am making a numeric text box, which can also contain various additional symbols to denote if the data contained in the control is a percentile, radius, etc. For this I have a grid with a text box to the left and a TextBlock to the right. Here is a picture:
The problem that I am having with this, however, is that if the mouse is over the textblock, and I click, I cannot get the TextBox to gain focus. I have tried _textbox.Focus() on mouse down of the textblock, as well as on the parent grid. This did not work.
After some googling, I read that I could put FocusManager.FocusedElement="{Binding ElementName=_textbox}" on the parent Grid, and this would solve my problem. However, even with this, the Textbox still does not gain focus. I've even tried making neither the textbox or textblock hit-testable, and instead use the grid itself as a hit test, but even with this, the textbox itself still will not gain focus. I'm at a loss of what to do here. Does anyone know how I can make the textbox gain focus, when either the parent grid is clicked, or the textblock is clicked? Or Both?
Here is my XAML:
<UserControl
x:Class="VoidwalkerEngine.Editor.Controls.NumericTextBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Height="32"
d:DesignWidth="80"
BorderThickness="0"
mc:Ignorable="d">
<UserControl.Resources>
<Style x:Key="ButtonTop" TargetType="Button">
<Setter Property="Background" Value="White" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
x:Name="ButtonBackground"
Background="{DynamicResource Voidwalker_Gradient_Button}"
BorderBrush="{DynamicResource Voidwalker_Brush_Border}"
BorderThickness="1,0,0,1"
CornerRadius="0,2,0,0">
<ContentPresenter
x:Name="contentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ButtonBackground" Property="Background" Value="{DynamicResource Voidwalker_Gradient_ButtonPressed}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="ButtonBackground" Property="Background" Value="{DynamicResource VoidwalkerButtonBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ButtonBottom" TargetType="Button">
<Setter Property="Background" Value="White" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
x:Name="ButtonBackground"
Background="{DynamicResource Voidwalker_Gradient_Button}"
BorderBrush="{DynamicResource Voidwalker_Brush_Border}"
BorderThickness="1,1,0,0"
CornerRadius="0,0,2,0">
<ContentPresenter
x:Name="contentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ButtonBackground" Property="Background" Value="{DynamicResource Voidwalker_Gradient_ButtonPressed}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="ButtonBackground" Property="Background" Value="{DynamicResource VoidwalkerButtonBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Border
Background="{DynamicResource Voidwalker_Brush_ContextArea}"
BorderBrush="{DynamicResource Voidwalker_Brush_Border}"
BorderThickness="1"
CornerRadius="3">
<Grid Focusable="False">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="23" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
BorderThickness="0"
CornerRadius="2,0,0,2">
<Grid
Cursor="IBeam"
FocusManager.FocusedElement="{Binding ElementName=_textbox}"
MouseDown="_backAreaGrid_OnClick">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
</Grid.ColumnDefinitions>
<TextBox
x:Name="_textbox"
Grid.Column="0"
Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Background="{DynamicResource VoidwalkerContextBrush}"
BorderThickness="0"
CommandManager.PreviewExecuted="_numericDisplayTextBox_OnPreviewExecuted"
Foreground="{DynamicResource Voidwalker_Brush_ActiveTextForeground}"
GotFocus="_textbox_OnGotFocus"
LostFocus="_numericDisplayTextBox_OnLostFocus"
MouseDoubleClick="_textbox_OnMouseDoubleClick"
PreviewKeyDown="_numericDisplayTextBox_OnPreviewKeyDown"
PreviewMouseWheel="_numericDisplayTextBox_OnPreviewMouseWheel"
Text="0"
TextAlignment="Right"
TextChanged="_numericDisplayTextBox_OnTextChanged" />
<TextBlock
x:Name="OperatorDisplayTextBox"
Grid.Column="1"
VerticalAlignment="Center"
Cursor="IBeam"
Foreground="{DynamicResource Voidwalker_Brush_ActiveTextForeground}"
Text="%" />
</Grid>
</Border>
<Button
Grid.Row="0"
Grid.Column="1"
BorderThickness="1,0,0,0"
Click="Increment_Button_OnClick"
Style="{DynamicResource ButtonTop}">
<Path Data="M 1,4.5 L 4.5,1 L 8,4.5" Fill="{DynamicResource Voidwalker_Brush_ActiveTextForeground}" />
</Button>
<Button
Grid.Row="1"
Grid.Column="1"
BorderThickness="1,0,0,0"
Click="Decrement_Button_OnClick"
Style="{DynamicResource ButtonBottom}">
<Path
ClipToBounds="True"
Data="M 1,1.5 L 4.5,5 L 8,1.5"
Fill="{DynamicResource Voidwalker_Brush_ActiveTextForeground}" />
</Button>
</Grid>
</Border>
</UserControl>
I figured it out after reading this page. I don't know why this code works...like, at all actually. It seems like i'm using a backwards, roundabout way into the control to avoid threading issues... isn't that what the Dispatcher is for? So is it safe to assume that a .Focus() method does nothing unless it's used like below? It's whatever, I guess, less hair pulling now, and more coding. Here is the code that worked for me. All I had to do was add this to the parent grid's MouseDown event:
private void _backAreaGrid_OnMouseDown(object sender, MouseButtonEventArgs e)
{
Dispatcher.BeginInvoke(
DispatcherPriority.ContextIdle,
new Action(delegate
{
_textbox.Focus();
}));
}
The textbox gains focus regardless of what I click on in the surrounding grid.

Can I reuse a Style using different DataTrigger Bindings?

I am working on a WPF 4.0 window with many status indicators using Labels. In one example, the Labels turn GREEN and read "Available" if the bound property's enumeration Foo is AVAILABLE. The labels turn RED and read "Not Available" if the bound property is NOTAVAILABLE. I also have other labels that indicate status of different bound enum Bar, and they turn different colors and have different content based on this value.
I am able to successfully bind and turn one label's color and text based on the value of a bound property. I use a rather lengthy ControlTemplate in a DataTrigger's Setter just to change the label's text.
Here's what I have so far:
<Window> ...
xmlns:cst="clr-namespace:CstCommonTypes;assembly=CstCommonTypes"
...
</Window>
<Label x:Name="Avail_Out_LBL" HorizontalAlignment="Left" Margin="111,44,0,0" VerticalAlignment="Top" Width="124" Height="18" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" SnapsToDevicePixels="False" Grid.Column="1" Padding="0">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Setter Property="Background" Value="#FFC08100"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="24"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Degraded"
Grid.Column="1"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding MonitorAndControlData.Availability}" Value="{x:Static cst:Foo.Available}">
<Setter Property="Background" Value="#FF567E4A"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="24"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Available"
Grid.Column="1"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding MonitorAndControlData.Availability}" Value="{x:Static cst:Foo.NotAvailable}">
<Setter Property="Background" Value="LightCoral"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="{TemplateBinding Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="22"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="22"/>
</Grid.ColumnDefinitions>
<TextBlock Text=" Not Available"
Grid.Column="1"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
Foreground="{TemplateBinding Foreground}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
The above works, but I was wondering if I can reuse either the Style and give it different DataTrigger bindings or just reuse the ControlTemplate to cut down on xaml code. I tried to see if I could define a resource, but I couldn't figure out how to give it different Template Bindings for all the Labels.
Any help would be greatly appreciated.
If you need more properties to bind to, then turn it into a custom control (i.e. a class that inherits from Control), then you can add additional dependency properties on said control, which you can then bind to in the template.
It won't be possible to reuse the style if the bindings are not the same.
What you could do is make yourself a user control for your status indicators labels, Inside which you will create a Dependency Property (lets name it Availability) on which you will bind your Triggers to. But, you will have to make sure that you will always need the same type for your triggers. If the Availability binding is not of the same type for each of your labels, this solution won't work.
Here is a link on how to use Dependency Properties :
http://www.wpftutorial.net/dependencyproperties.html

How to get control used in template in user control code?

How could I get a DataGrid control used in xaml style template to use it in code?
<UserControl>
<UserControl.Resources>
<Style x:Key="MyComboBoxStyle" TargetType="{x:Type ComboBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid x:Name="MainGrid" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="0" MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup"
Grid.ColumnSpan="2">
<Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw">
<Border x:Name="DropDownBorder">
<DataGrid x:Name="PART_PopupDataGrid" />
</Border>
</Microsoft_Windows_Themes:SystemDropShadowChrome>
</Popup>
<ToggleButton Grid.ColumnSpan="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
IsChecked="{Binding Path=IsDropDownOpen,
Mode=TwoWay,
RelativeSource={RelativeSource TemplatedParent}}"
Style="{StaticResource ComboBoxReadonlyToggleButton}" />
<ContentPresenter Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding SelectionBoxItem}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
IsHitTestVisible="false"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<ComboBox Name="ComboGrid" Style="{DynamicResource DataGridComboBoxStyle}" />
</Grid>
</UserControl>
There is how I tried to get DataGrid control in user control, but not successfully:
var v1 = this.FindName("PART_PopupDataGrid");
var v2 = this.Template.FindName("PART_PopupDataGrid", this);
var v3 = ComboGrid.FindName("PART_PopupDataGrid");
How could I get this control in code?
This is a very common requirement. In fact, it's so common that Microsoft even have a page on MSDN specifically for this:
How to: Find ControlTemplate-Generated Elements
Basically, if you have a reference to the ComboBox that the ControlTemplate is applied to (let's call it ComboBox), then you should be able to do this:
DataGrid dataGrid =
ComboBox.Template.FindName("PART_PopupDataGrid", ComboBox) as DataGrid;

Windows Phone 8, remove the Header of each PivotItem

I struggled with this problem for hours. I want to use the control Pivot as a Pager in Windows Phone, so I want to remove the Header of each PivotItem. What I have done is to create a DataTemplage for the Pivot's HeaderTemplate, as below:
<DataTemplate x:Name="DataTemplateScrollTestItemHeader"
x:Key="DataTemplateScrollTestItemHeader">
<TextBlock
Height="0"
Width="0"
Margin="0,0,0,0"
Padding="0,0,0,0"
Text=""/>
</DataTemplate>
In code, I set the HeaderTemplate to this DataTemplate:
PivotTestType.HeaderTemplate = DataTemplateScrollTestItemHeader;
What happened is the header text is disappeared, but the header still occupied some space. I have read this:
Windows Phone 8: remove pivot header
But it's the same with my method. It can't remove the space of the Header.
Anyone know how to handle this?
I think the best would be to underdstand how the pivot is constructed (with this you will be able to do whatever you want with your pivot), I wrote a small example which may help you:
<phone:Pivot Name="myPivot" VerticalAlignment="Stretch" Title="myPivot">
<phone:Pivot.Template>
<ControlTemplate TargetType="phone:Pivot">
<Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentPresenter ContentTemplate="{TemplateBinding TitleTemplate}"
Content="{TemplateBinding Title}" Margin="10,0,0,0"/>
<primitives:PivotHeadersControl x:Name="HeadersListElement" Grid.Row="1" Margin="0,5,0,5"/>
<ItemsPresenter x:Name="PivotItemPresenter" Margin="{TemplateBinding Padding}" Grid.Row="2"/>
</Grid>
</ControlTemplate>
</phone:Pivot.Template>
<phone:Pivot.HeaderTemplate>
<DataTemplate>
<Grid Height="30">
<TextBlock Text="{Binding}" FontSize="{StaticResource PhoneFontSizeMediumLarge}" Margin="0,0,10,0"/>
</Grid>
</DataTemplate>
</phone:Pivot.HeaderTemplate>
<phone:PivotItem Margin="0">
</phone:PivotItem>
</phone:Pivot>
With the code above you can change height, background color etc. of pivot title, header itempresenter and so on.
And don't forget to add xmlns-primitives at the beginning of xaml:
xmlns:primitives="clr-namespace:Microsoft.Phone.Controls.Primitives;assembly=Microsoft.Phone"
You can also find more on this site or MSDN: this, MSDN.
Remove all Headers from PivotItems and build (F6) the application.
<phone:Pivot Title="MY APPLICATION">
<phone:PivotItem>
// Some code
</phone:PivotItem>
<phone:PivotItem>
// Some code
</phone:PivotItem>
</phone:Pivot>
Hy, Here is my solution to remove the header and title :
<phone:PhoneApplicationPage.Resources>
<Style x:Key="PivotWithoutHeaderTitleStyle" TargetType="phone:Pivot">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Foreground" Value="Transparent"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:Pivot">
<Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentControl ContentTemplate="{TemplateBinding TitleTemplate}" Content="{TemplateBinding Title}" HorizontalAlignment="Left" Margin="0" Height="0"/>
<Primitives:PivotHeadersControl x:Name="HeadersListElement" Margin="0" Height="0"/>
<ItemsPresenter x:Name="PivotItemPresenter" Margin="{TemplateBinding Padding}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ImagePivotItemStyle" TargetType="phone:PivotItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:PivotItem">
<Grid Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Pivot">
<VisualState x:Name="Right"/>
<VisualState x:Name="Left"/>
<VisualState x:Name="Center"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Resources> <phone:Pivot Name="ImagesPivot" Margin="0,0,0,0" Style="{StaticResource PivotWithoutHeaderTitleStyle}" ItemContainerStyle="{StaticResource ImagePivotItemStyle}">
<phone:Pivot.TitleTemplate>
<DataTemplate/>
</phone:Pivot.TitleTemplate>
<phone:Pivot.HeaderTemplate>
<DataTemplate/>
</phone:Pivot.HeaderTemplate>
<phone:Pivot.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
Hope that will help

Categories