Silverlight Tooltip Style ContentPresenter TextWrapping - silverlight

I want to create a Silverlight Tooltip Style but I don't want to use a textblock because the tooltip content might be an image or something else. So I'm using a ContentPresenter. My problem is how to set MaxWidth and force TextWrapping when content is text. This is what I have so far:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit">
<Style TargetType="ToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border BorderBrush="DimGray" BorderThickness="1" CornerRadius="5" Background="WhiteSmoke" Opacity="0.8"
HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,10,0,-5" Width="Auto">
<Border.Effect>
<DropShadowEffect BlurRadius="16" ShadowDepth="8" Direction="-45" Color="Black" Opacity="0.6"/>
</Border.Effect>
<Grid>
<ContentPresenter Content="{TemplateBinding Content}" Margin="3"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

I found one way to do this:
Create 2 Tooltip styles - one for text and another for everything else, like this:
<Style x:Key="TooltipStyleForText" TargetType="ToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border BorderBrush="DimGray" BorderThickness="1" CornerRadius="5" Background="WhiteSmoke" Opacity="0.8"
HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,10,0,-5" Width="Auto">
<Border.Effect>
<DropShadowEffect BlurRadius="16" ShadowDepth="8" Direction="-45" Color="Black" Opacity="0.6"/>
</Border.Effect>
<Grid>
<TextBlock Text="{TemplateBinding Content}" MaxWidth="400" TextWrapping="Wrap" Margin="3"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TooltipStyleForOtherStuffThanText" TargetType="ToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border BorderBrush="DimGray" BorderThickness="1" CornerRadius="5" Background="WhiteSmoke" Opacity="0.8"
HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,10,0,-5" Width="Auto">
<Border.Effect>
<DropShadowEffect BlurRadius="16" ShadowDepth="8" Direction="-45" Color="Black" Opacity="0.6"/>
</Border.Effect>
<Grid>
<ContentPresenter Content="{TemplateBinding Content}" Margin="3"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and than when we use a TextBlock, call it's ToolTip style like this:
<TextBlock Text="something">
<ToolTipService.ToolTip>
<ToolTip Style="{StaticResource TooltipStyleForText}">
<TextBlock Text="Some text"/>
</ToolTip>
</ToolTipService.ToolTip>
</TextBlock>
This might not be the best solution because we have two styles so we need to specify write several lines for a simple TextBlock.
I hope someone has a better solution.

We needed to do the same thing and tried a few approaches before setting on the following solution. The problem is that when the ToolTip.Content is a string you need to show the tooltip using a TextBlock. When ToolTip.Content is not a string you need to use a ContentPresenter. So we ended up defining a ControlTemplate that has both, and we show/hide the appropriate one based on the type of ToolTip.Content. This approach is applied to all ToolTips in the application:
The following converter class helps out with this:
public class TooltipContentVisibilityConverter : IValueConverter
{
public Visibility VisibilityWhenToolTipContentIsAString { get; set; }
public Visibility VisibilityWhenToolTipContentIsNotAString { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var toolTip = value as ToolTip;
if (toolTip != null && toolTip.Content is string)
{
return VisibilityWhenToolTipContentIsAString;
}
return VisibilityWhenToolTipContentIsNotAString;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then in your App.xaml you define the following.
<Converter:TooltipContentVisibilityConverter VisibilityWhenToolTipContentIsAString="Visible" VisibilityWhenToolTipContentIsNotAString="Collapsed" x:Key="tooltipStringContentVisibilityConverter" />
<Converter:TooltipContentVisibilityConverter VisibilityWhenToolTipContentIsAString="Collapsed" VisibilityWhenToolTipContentIsNotAString="Visible" x:Key="tooltipNonStringContentVisibilityConverter" />
<Style TargetType="ToolTip">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Border CornerRadius="0" Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1" Padding="4">
<StackPanel Orientation="Vertical">
<TextBlock Text="{TemplateBinding Content}" TextWrapping="Wrap" MaxWidth="300"
Visibility="{Binding RelativeSource={RelativeSource AncestorType=ToolTip},Converter={StaticResource tooltipStringContentVisibilityConverter}}"/>
<ContentPresenter Content="{TemplateBinding Content}"
Visibility="{Binding RelativeSource={RelativeSource AncestorType=ToolTip},Converter={StaticResource tooltipNonStringContentVisibilityConverter}}"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It seems like a bit of an awkward way to have to solve this problem, but it does work and we haven't found a better solution yet.

Related

Making the header of a group box unique for each instance

I have created a Groupbox resource directory, and created a style that affects the groupbox.
Here is my Resource Directory code:
<Style x:Key="grpNumbers" TargetType="GroupBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<Border
BorderThickness="1"
BorderBrush="#25A0DA" CornerRadius="10">
<Label HorizontalAlignment="Left" Content="Carrier" Foreground="White" Background="#151515" Height="38"
Margin="30,-195,0,0"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The issue is that I want the group box style to not be coupled with the Content in the Label.
Currently it is getting instantiated in the mainwindow like this:
<GroupBox Style="{StaticResource ResourceKey=grpNumbers}" Grid.Column="1" BorderBrush="#272727" Grid.Row="1" Height="200" Margin="20" HorizontalAlignment="Stretch" Header="Carrier information" Foreground="White" FontSize="20" BorderThickness="0.2">
</GroupBox>
But obviously the above groupboxes' Header tag isn't overriding the header of my custom groupbox but I need it too, can this be done?
Label inside ContentTemplate can use TemplateBinding to bind Header:
<Label Content="{TemplateBinding Header}"/>
You should modify your Style too look like this:
<Style x:Key="grpNumbers" TargetType="{x:Type GroupBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupBox}">
<Grid>
<Border BorderThickness="1"
BorderBrush="#25A0DA"
CornerRadius="10">
<Label HorizontalAlignment="Left"
Content="{TemplateBinding Header}"
Foreground="White"
Background="#151515"
Height="38"
Margin="30,-195,0,0"/>
</Border>
<!-- Responsible for displaying what you put inside of your GroupBox -->
<ContentPresenter Margin="5,25,5,5" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
which can then be used like this:
<GroupBox Style="{StaticResource grpNumbers}"
Grid.Column="1"
BorderBrush="#272727"
Grid.Row="1"
Height="200"
Margin="20"
HorizontalAlignment="Stretch"
Header="Carrier information"
Foreground="White"
FontSize="20"
BorderThickness="0.2">
<TextBox /> <!-- or whatever you want inside your GroupBox -->
</GroupBox>

Datagrid, Merge/Combine rows, cells and columns

I'm trying to acomplish exactly what this question is requesting, but unfortunately the code sample that was provided as the answer is gone, and I'm also not using WPF Toolkit, here the question that he did:
I am trying to Merge cells in WPF toolkit datagrid .I am trying to do something as shown in the image below.We can do this in Winforms datagrid.But how to do this using WPF toolkit datagrid ?.Or is there any alternative controls..?
Can we do this using listview or listbox..? Or is there any free
controls available which have this functionality ?
I found several answers that manage to do this with the DataGridView control, but I do not want to use Form objects in a WPF project, is there a way to acomplish this?
Recource
<Window.Resources>
<Color x:Key="customBlue" A="255" R="54" G="95" B="177" />
<SolidColorBrush x:Key="customBlueBrush" Color="{StaticResource customBlue}"></SolidColorBrush>
<SolidColorBrush x:Key="customBlueBrushOpacity" Color="LightGray" Opacity="0.11"></SolidColorBrush>
<Style x:Key="calcyListbox" TargetType="ListBox">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="35"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Height="30" VerticalAlignment="Top" Background="{StaticResource customBlueBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="Manufacturer" FontSize="14" FontFamily="Segoe Ui Dark" Foreground="White" SnapsToDevicePixels="True" HorizontalAlignment="Center" VerticalAlignment="Center" ></TextBlock>
<TextBlock Text="Name" FontSize="14" FontFamily="Segoe Ui Dark" Foreground="White" SnapsToDevicePixels="True" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1"></TextBlock>
<TextBlock Text="CPU" FontSize="14" FontFamily="Segoe Ui Dark" Foreground="White" SnapsToDevicePixels="True" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="2"></TextBlock>
<TextBlock Text="RAM" FontSize="14" FontFamily="Segoe Ui Dark" Foreground="White" SnapsToDevicePixels="True" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="3"></TextBlock>
<TextBlock Text="Price" FontSize="14" FontFamily="Segoe Ui Dark" Foreground="White" SnapsToDevicePixels="True" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="4"></TextBlock>
</Grid>
<Border Grid.Row="1" SnapsToDevicePixels="True" Background="Transparent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0">
<ScrollViewer x:Name="ScrollViewer" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="0">
<ItemsPresenter />
</ScrollViewer>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="noStyleToListboxItem" TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border>
<ContentPresenter></ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
xaml
<ListBox MaxHeight="300" ItemsSource="{Binding ManufacturerList}" Background="{StaticResource customBlueBrushOpacity}" x:Name="ManufacturerListBox" ScrollViewer.VerticalScrollBarVisibility="Auto" Style="{StaticResource calcyListbox}" ItemContainerStyle="{StaticResource noStyleToListboxItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Company}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Border BorderThickness="0,0,0,1" BorderBrush="Black" ></Border>
<ListBox Grid.Column="1" BorderThickness="1,0,1,1" Background="{StaticResource customBlueBrushOpacity}" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Models}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Border BorderThickness="0,0,1,0" BorderBrush="Black" Margin="-2" Grid.Column="0"></Border>
<Border BorderThickness="0,0,1,0" BorderBrush="Black" Margin="-2" Grid.Column="1"></Border>
<Border BorderThickness="0,0,1,0" BorderBrush="Black" Margin="-2" Grid.Column="2"></Border>
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="0"/>
<TextBlock Text="{Binding CPU}" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1"/>
<TextBlock Text="{Binding Ram}" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="2"/>
<TextBlock Text="{Binding price}" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="3"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
c#
InitializeComponent();
List<Manufacturer> ManufacturerList = new List<Manufacturer>();
ManufacturerList.Add(new Manufacturer()
{
Company = "DEll",
Models = new List<Model>(){new Model(){CPU = "T7250", Name = "Inspiron1525", price =234434 , Ram= "2048 MB" },
new Model(){CPU = "T5750", Name = "Studio 1535", price =234443 , Ram= "2048 MB" },
new Model(){CPU = "T5780", Name = "Vastro 1510", price =234434 , Ram= "2048 MB" },}
});
ManufacturerList.Add(new Manufacturer()
{
Company = "Lenovo",
Models = new List<Model>(){new Model(){CPU = "T1230", Name = "l123", price =23546454 , Ram= "1024 MB" },
new Model(){CPU = "T1230", Name = "l1423", price =2346456 , Ram= "1024 MB" },
new Model(){CPU = "T1230", Name = "ldf123", price =2344646 , Ram= "1024 MB" },}
});
ManufacturerListBox.ItemsSource = ManufacturerList;
public class Manufacturer
{
public string Company { get; set; }
public List<Model> Models { get; set; }
}
public class Model
{
public string Name { get; set; }
public string Ram { get; set; }
public double price { get; set; }
public string CPU { get; set; }
}
For a merged cell, bind its Margin and set it to a negative value equal to the sum width/height of the associated merged cells - then the cell will spill across and on top the neighboring cells.
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="{{Binding BorderThickness[5], Mode=OneWay}}"/>
<Setter Property="Margin" Value="{{Binding CellMargins[5], Mode=OneWay}}"/>
<Setter Property="Block.TextAlignment" Value="Center"/>
</Style>
The bindings are indexed because CellMargins is an ObservableCollection of Thickness. The viewmodel is row-level, so each column binds to a different index.
Before this gets downvoted, let me say this can lead to some undesirable visual quirks. Getting this to work perfectly requires a bit of code-behind, such as:
The cell margins' negative values need to be updated whenever a column width changes, so I handled the datagrid's LayoutUpdated event, where I iterated through the columns, measured their current ActualWidths and updated the margins accordingly. I likewise update the BorderThickness to show/hide cell borders as needed. Disabling the selection highlight for cells that are "hidden" is another trick.
Note this means keeping track of what cells (i.e., which row viewmodels and column indices) you want merged separately in code-behind.
This method is complicated and probably not the easiest for every situation, but I found it useful for my purposes. I needed a Datagrid where the user could merge/unmerge cells and create/delete columns, similar to Excel. Furthermore, I wanted to stick with DataGridTextColumns (instead of custom TemplateColums) because of their built-in functionality (recognized keyboard edit commands, copy/paste, etc.)

Template Binding in Control template

I have the following control template.
I wish to set the source property for the image control in the control
template using Template Binding.
But since this is a control template for button control and the button control doesn't
have source property, i can't use TemplateBinding in this case.
<ControlTemplate x:Key="BtnTemplate" TargetType="Button">
<Border CornerRadius="5" Margin="15" Cursor="Hand">
<StackPanel>
<Image Name="Img" Style="{StaticResource ImageStyle}" Source="temp.jpg" Height="100" Width="100" Margin="5"></Image>
<Label Content="{TemplateBinding Content}" Background="Transparent" Margin="2"></Label>
</StackPanel>
</Border>
</ControlTemplate>
Since i have to set different images for different instances of button, i can't hardcode the path as well.
Please let me know how to tackle this situation.
I'd suggest using dynamic resources, e.g. define the template as follows:
<ControlTemplate x:Key="buttonTemplate" TargetType="Button">
<Border CornerRadius="5" Margin="15" Cursor="Hand">
<StackPanel Orientation="Horizontal" Background="Yellow">
<Image Source="{DynamicResource ResourceKey=Img}" Height="100" Width="100" Margin="5"></Image>
<Label Content="{TemplateBinding Content}" Background="Transparent" Margin="2"></Label>
</StackPanel>
</Border>
</ControlTemplate>
And use it like this:
<Button Content="Button" Template="{StaticResource ResourceKey=buttonTemplate}">
<Button.Resources>
<ImageSource x:Key="Img">SomeUri.png/</ImageSource>
</Button.Resources>
</Button>
TemplateBinding is a lightweight "binding", it doesn't support some features of traditional Binding, such as automatically type conversion using the known type converters associated with the target property (such as converting the string URI into a BitmapSource instance).
The following code can work properly:
<Window x:Class="GridScroll.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2">
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="ButtonStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" Margin="15" Cursor="Hand" Background="Red">
<StackPanel Orientation="Horizontal" Background="White">
<Image Name="Img" Source="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}" Margin="5"></Image>
<Label Content="{TemplateBinding Content}" Margin="2"></Label>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel Orientation="Horizontal">
<Button Style="{StaticResource ButtonStyle}" Tag="a.jpeg" Content="a"/>
<Button Style="{StaticResource ButtonStyle}" Tag="b.png" Content="b"/>
</StackPanel>
You haven't really said how you expect consumers of your button to set the source. You could use the Button.Tag property, for example, and then bind to that in your template. Or you could define your own control:
public class ImageButton : Button
{
// add Source dependency property a la Image
}
And then the template:
<ControlTemplate TargetType="ImageButton">
<Border CornerRadius="5" Margin="15" Cursor="Hand">
<StackPanel>
<Image Name="Img" Style="{StaticResource ImageStyle}" Source="{TempateBinding Source}" Height="100" Width="100" Margin="5"></Image>
<Label Content="{TemplateBinding Content}" Background="Transparent" Margin="2"></Label>
</StackPanel>
</Border>
</ControlTemplate>
I'm not sure that I understood your problem very well but why don't you use ContentPresenter? It allows to move the code for your Image at the higher level.
<ControlTemplate x:Key="BtnTemplate" TargetType="Button">
...
<ContentPresenter/>
</ControlTemplate>
...
<Button Template="{StaticResource BtnTemplate}">
<Image .../>
</Button>

WPF Buttons Style

I have WPF Form which has many buttons with the same code. Appearance of all buttons must be the same
For example, code for one of these buttons
<Button x:Name="btnAddRelative" Width="120" Click="btnAddRelative_Click" >
<Button.Content>
<StackPanel Orientation="Horizontal">
<Image Height="26" HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="images/add.png" />
</Image.Source>
</Image>
<TextBlock Text=" Add Relative" Height="20" VerticalAlignment="Center"/>
</StackPanel>
</Button.Content>
</Button>
How can I create one style and use it for all my buttons. All buttons has the same png image, only their text different. How can I do this.
I tried to do this with Style object in Resource Section:
<UserControl.Resources>
<Style TargetType="Button" x:Key="AddStyle">
<Setter Property="Content">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<Image Height="26" HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="images/add.png" />
</Image.Source>
</Image>
<TextBlock Text=" " Height="20" VerticalAlignment="Center"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
But this code not work. Can any body know how can I do this?
If the image is fix you can hard-code it in the style, and use the Content property of Button bin to the Content of TextBox
<Style x:Key="ButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel
Orientation="Horizontal">
<!--<Image Height="26" HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="images/add.png" />
</Image.Source>
</Image>-->
<TextBlock
Foreground="{TemplateBinding Foreground}"
Text="{TemplateBinding Content}"
Height="20"
VerticalAlignment="{TemplateBinding VerticalAlignment}"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
just try this
<Window.Resources>
<Style TargetType="Button"
x:Key="AddStyle">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<StackPanel Orientation="Horizontal">
<Image Height="26"
Width="20"
HorizontalAlignment="Left">
<Image.Source>
<BitmapImage UriSource="/WpfApplication33;component/Images/MoveLeft.png" />
</Image.Source>
</Image>
<TextBlock Text ="{TemplateBinding Content}"
Height="20"
/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button Style="{StaticResource AddStyle}"
Height="25" Width="100"
Content="Button1"></Button>
<Button Style="{StaticResource AddStyle}"
Height="25"
Width="100"
Content="Button22"></Button>
<Button Style="{StaticResource AddStyle}"
Height="25"
Width="100"
Content="Button2233"></Button>
<Button Style="{StaticResource AddStyle}"
Height="25"
Width="100"
Content="Button2332"></Button>
</StackPanel>
</Grid>
Note: Use ContentPresenter instead of TextBlock if you have to display anything other than flat text
Try changing your style as follows
<UserControl.Resources>
<Style
TargetType="Button"
x:Key="AddStyle">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel
Orientation="Horizontal">
<Image
Height="26"
HorizontalAlignment="Left">
<Image.Source>
<BitmapImage
UriSource="images/add.png" />
</Image.Source>
</Image>
<TextBlock
Text=" "
Height="20"
VerticalAlignment="Center" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
[Edit inspired by comment]
You could create a new UserControl, lets call it AddButtonContent containing your Stackpanel and such, then include that within your button, like so:
<Button>
<local:AddButtonContent
ButtonText="Testing, one, two, three" />
</Button>
You'll need to add a xmlns reference called local (or whatever you'd like to call it) to the UserControl with all of the buttons.
The codebehind portion of your AddButtonContent UserControl will need the following code, and you'll need to name your TextBlock (I used testText for this example).
public static DependencyProperty ButtonTextProperty =
DependencyProperty.Register("ButtonText",
typeof(string),
typeof(AddButtonContent),
new PropertyMetadata("", onTextChangedCallback));
public string ButtonText
{
get { return (string)GetValue(ButtonTextProperty); }
set
{
SetValue(ButtonTextProperty, value);
}
}
static void onTextChangedCallback(
DependencyObject dobj,
DependencyPropertyChangedEventArgs args)
{
AddButtonContent abc = dobj as AddButtonContent;
abc.testText.Text = args.NewValue.ToString();
}

Data Template not injected in ItemContainer

I have an ItemsControl class that overrides the following methods:
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is TilePanelItem;
}
protected override DependencyObject GetContainerForItemOverride()
{
return new TilePanelItem();
}
I provided the template for TilePanelItem which is the container of ItemsControl:
<ControlTemplate x:Key="tileItemTemplate" TargetType="my:TilePanelItem">
<Grid Width="200" Height="100">
<Border BorderBrush="Black" BorderThickness="2">
<ContentPresenter RenderTransformOrigin=".5,.5" />
</Border>
</Grid>
</ControlTemplate>
And the Style for it:
<Style TargetType="my:TilePanelItem">
<Setter Property="Template" Value="{StaticResource tileItemTemplate}" />
</Style>
And finally the instance of my ItemsControl with the DataTemplate:
<my:TileItemsControl x:Name="tileControl" ItemsSource="{Binding}" >
<my:TileItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</my:TileItemsControl.ItemsPanel>
<my:TileItemsControl.ItemTemplate>
<DataTemplate>
<Border Background="Blue">
<TextBlock Text="here I am" />
</Border>
</DataTemplate>
</my:TileItemsControl.ItemTemplate>
</my:TileItemsControl>
The DataTemplate that I defined is not injected in ItemContainer. When I run the app, it shows the borders as I declared in ItemContainter template but I don't see the DataTemplate.
What am I missing?
Thanks a million
You need to bring the ItemsTemplate in to become the ContentPresenter's ContentTemplate:
<ControlTemplate x:Key="tileItemTemplate" TargetType="my:TilePanelItem">
<Grid Width="200" Height="100">
<Border BorderBrush="Black" BorderThickness="2">
<ContentPresenter RenderTransformOrigin=".5,.5"
ContentTemplate="{Binding ItemsTemplate, RelativeSource={RelativeSource FindAncestor,my:TileItemsControl,1}}" />
</Border>
</Grid>
</ControlTemplate>

Resources