i have a problem with the ToolTips and need some helping hand.
I want to create a custom design for all tooltips, adding a header and a footer.
Because it should be the default tooltip style/template i created attached properties, to set the values for header and footer on all UI elements.
public class ToolTipExtensions
{
public static readonly DependencyProperty HeaderProperty = DependencyProperty.RegisterAttached("Header",
typeof(string), typeof(ToolTipExtensions), new PropertyMetadata(null));
public static readonly DependencyProperty FooterProperty = DependencyProperty.RegisterAttached("Footer",
typeof(string), typeof(ToolTipExtensions), new PropertyMetadata(null));
public static void SetHeader(UIElement element, string value)
{
element.SetValue(HeaderProperty, value);
}
public static string GetHeader(UIElement element)
{
return (string)element.GetValue(HeaderProperty);
}
public static void SetFooter(UIElement element, string value)
{
element.SetValue(FooterProperty, value);
}
public static string GetFooter(UIElement element)
{
return (string)element.GetValue(FooterProperty);
}
}
Im using the following style.
<Style TargetType="{x:Type ToolTip}">
<Setter Property="MinHeight" Value="150" />
<Setter Property="Width" Value="350" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="#ECEFF4" />
<Setter Property="BorderBrush" Value="#394F6D" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolTip}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,1">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
MinHeight="40"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ToolTipExtensions.Header)}"
FontFamily="Arial"
FontSize="13"
FontWeight="Bold"
Foreground="{TemplateBinding Foreground}" />
<TextBlock
Grid.Row="1"
MinHeight="40"
Foreground="{TemplateBinding Foreground}"
Text="{Binding ToolTip, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
<Label
Grid.Row="2"
MinHeight="30"
Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ToolTipExtensions.Footer)}"
FontFamily="Arial"
FontSize="12"
FontStyle="Italic"
FontWeight="Regular" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Im doing something wrong, because the tooltip dosent show anything. No ToolTip, no Header, no Footer.
Whats the problem with it? Wrong DataContext for the ToolTip?
Heres the usage:
<Button
local:ToolTipExtensions.Header="Button"
local:ToolTipExtensions.Footer="To show additional Info"
Content="Test"
ToolTip="Some fancy Text"
ToolTipService.InitialShowDelay="500"
ToolTipService.ShowDuration="999999999" />
Regards,
SyLuS
ToolTip for every control will be updated
Modified Style
<VM:DependecnyObjectTypeConverter x:Key="ConverterPa"/>
<Style TargetType="{x:Type ToolTip}">
<Setter Property="MinHeight" Value="150" />
<Setter Property="Width" Value="350" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="#ECEFF4" />
<Setter Property="BorderBrush" Value="#394F6D" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,1">
<Grid Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
MinHeight="40"
Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Converter={StaticResource ConverterPa},ConverterParameter=Header}"
FontFamily="Arial"
FontSize="13"
FontWeight="Bold"
Foreground="{TemplateBinding Foreground}" />
<TextBlock
Grid.Row="1"
MinHeight="40"
Foreground="{TemplateBinding Foreground}"
Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Converter={StaticResource ConverterPa},ConverterParameter=ToolTip}"/>
<Label
Grid.Row="2"
MinHeight="30"
Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Converter={StaticResource ConverterPa},ConverterParameter=Footer}"
FontFamily="Arial"
FontSize="12"
FontStyle="Italic"
FontWeight="Regular" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
IValueConverter:
public class DependecnyObjectTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var plTarget = value as System.Windows.Controls.ToolTip;
if (parameter.ToString() == "Header")
{
return plTarget.PlacementTarget.GetValue(ToolTipExtensions.HeaderProperty);
}
if (parameter.ToString() == "ToolTip")
{
return plTarget.PlacementTarget.GetValue(Control.ToolTipProperty);
}
if (parameter.ToString() == "Footer")
{
return plTarget.PlacementTarget.GetValue(ToolTipExtensions.HeaderProperty);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Related
My code:
<DataGrid HorizontalAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Hidden" BorderBrush="#83D744" IsSynchronizedWithCurrentItem="False" VerticalGridLinesBrush="Transparent" Grid.Column="0" RowHeaderWidth="0" CanUserAddRows="False" AutoGenerateColumns="False" x:Name="datagrid1" Margin="10,150,8,50" Background="Transparent" RowBackground="#FF494949" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ItemsSource="{Binding}">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#83D744"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="50"/>
</Style>
<Style x:Key="TextInCellCenter" TargetType="{x:Type TextBlock}" >
<Setter Property="TextAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="RightAligElementStyle">
<Setter Property="TextAlignment" Value="Right"/>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="LeftAligElementStyle">
<Setter Property="TextAlignment" Value="Left"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent"/>
</DataGrid.Resources>
<DataGrid.Columns >
<DataGridTextColumn Binding="{Binding ProductName}" ElementStyle="{StaticResource LeftAligElementStyle}" Header="NAZIV ARTIKLA" MinWidth="350" Foreground="White" FontSize="20" FontFamily="Verdana" />
<DataGridTextColumn Binding="{Binding Quantity}" ElementStyle="{StaticResource TextInCellCenter}" Header="KOLIČINA" MinWidth="200" Foreground="White" FontSize="20" FontFamily="Verdana" />
</DataGrid.Columns>
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="Black" Opacity="0.7">
<Expander.Header >
<DockPanel Height="50" Margin="0,0,0,0" Name="dockPanel" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=ActualWidth}">
<Button Name="btnFinishOrder" Content="Finish Order" Margin="0,0,55,5" DockPanel.Dock="Right" Click="btnFinishOrder_Click" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush= "{TemplateBinding BorderBrush}"
Background= "{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button Name="btnTakeIt" Click="btnTakeIt_Click" Content="Take it" Margin="0,0,20,5" DockPanel.Dock="Right" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Path=Name,StringFormat= Number of Order:# {0}}" />
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
There you can see guys, when I click on button Click="btnTakeIt_Click" I programaticaly change buttons text to "Order in progress." and I update field in my database IsInProgres to 1 - true, code is here:
private void btnTakeIt_Click(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
CollectionViewGroup group = b.DataContext as CollectionViewGroup;
var x = group.Name;
int orderNumber = Convert.ToInt32(x);
b.BorderBrush = null;
b.Content = "Order is in progress";
b.FontSize = 12;
OrdersController.SetOrderInProgressByID(orderNumber);
}
But what is happening, because I'm refreshing my grid every 20 seconds my button content is becoming again like it's on default "Take it!" because that's whats written in XAML.
Like this:
This is my code behind (refresh every few seconds):
public MainWindow()
{
try
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
this.WindowState = WindowState.Maximized;
var ordersList = OrdersController.localOrders();
collectionViewSource.Source = ordersList;
collectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder"));
DataContext = collectionViewSource;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(20);
timer.Tick += timer_Tick;
timer.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void timer_Tick(object sender, EventArgs e)
{
var ordersList = OrdersController.localOrders();
collectionViewSource.Source = null;
collectionViewSource.Source = ordersList;
DataContext = collectionViewSource;
datagrid1.ScrollIntoView(datagrid1.Items[datagrid1.Items.Count - 1]);
}
}
So my question is could I somehow loop my localOrders and check if NumberOfOrder has IsInProgress = 1 and simply set this:
btnTakeIt.Content="Order in progress.."
So everytime my grid refresh I can loop my orders, and check is order InProgress and after that I can set button btnTakeIt content to "Order in progress.."
Or if there is any other way, I am opened to try it!
P.S I tried allready but my btnTakeIt is not accessible in code behind :(
EDIT:
void timer_Tick(object sender, EventArgs e)
{
Button MyButton = FindChild<Button>(datagrid1, "btnTakeIt");
var ordersList = OrdersController.localOrders();
collectionViewSource.Source = null;
collectionViewSource.Source = ordersList;
foreach (var item in ordersList)
{
if (item.IsInProgress== true)
{
MyButton.Content = "Order is in progress";
}
}
DataContext = collectionViewSource;
}
Can I do it like this? I checked debuger and it is entering inside of if statement and when I look at breakpoint it acctualy changes content but on grid I can not see anything changed :(
EDIT:
I have to mention that my class Product is contained in my OrdersController :)
#Ayuman
what do you think about this:
<Button Name="btnTakeIt" DataContext="{Binding Items[0]}" Content="{Binding Status}"Click="btnTakeIt_Click" Content="Take it" Margin="0,0,20,5" DockPanel.Dock="Right" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
code behind:
public static List<LocalOrders> localOrders()
{
var results = DataServices.POS.proc_GetAllOrders().ToList();
List<LocalOrders> localOrdersList = new List<LocalOrders>();
foreach (var item in results)
{
LocalOrders lokal = new LocalOrders();
if (item.IsInProgress)
{
localo.Pihvacena = true;
localo.Status = "IN PROCESS";
}
else
{
lokalne.Status = "IT IS NOT YET IN PROCESS";
}
lokal.User = item.User;
lokal.Quantity = Convert.ToInt32(item.Quantity);
lokal.Title = item.Title;
lokal.NumberOfOrder = item.NumberOfOrder;
localOrdersList.Add(lokal);
}
return localOrdersList;
}
So I can programaticaly check for status of order and set content of button like that.. is it good solution maybe?
Please refer below code. I tried to make it work. Hope this works for you as well
<DataGrid HorizontalAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Hidden" BorderBrush="#83D744" IsSynchronizedWithCurrentItem="False" VerticalGridLinesBrush="Transparent" Grid.Column="0" RowHeaderWidth="0" CanUserAddRows="False" AutoGenerateColumns="False" x:Name="datagrid1" Margin="10,150,8,50" Background="Transparent" RowBackground="#FF494949" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ItemsSource="{Binding}">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="#83D744"/>
<Setter Property="Opacity" Value="1"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="18"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="50"/>
</Style>
<Style x:Key="TextInCellCenter" TargetType="{x:Type TextBlock}" >
<Setter Property="TextAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="RightAligElementStyle">
<Setter Property="TextAlignment" Value="Right"/>
</Style>
<Style TargetType="{x:Type TextBlock}" x:Key="LeftAligElementStyle">
<Setter Property="TextAlignment" Value="Left"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent"/>
</DataGrid.Resources>
<DataGrid.Columns >
<DataGridTextColumn Binding="{Binding ProductName}" ElementStyle="{StaticResource LeftAligElementStyle}" Header="NAZIV ARTIKLA" MinWidth="350" Foreground="White" FontSize="20" FontFamily="Verdana" />
<DataGridTextColumn Binding="{Binding Quantity}" ElementStyle="{StaticResource TextInCellCenter}" Header="KOLIČINA" MinWidth="200" Foreground="White" FontSize="20" FontFamily="Verdana" />
</DataGrid.Columns>
<DataGrid.GroupStyle>
<!-- Style for groups at top level. -->
<GroupStyle>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" Background="Black" Opacity="0.7">
<Expander.Header >
<DockPanel Height="50" Margin="0,0,0,0" Name="dockPanel" Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}, Path=ActualWidth}">
<Button Name="btnFinishOrder" DataContext="{Binding Items[0]}" Content="{Binding ButtonCaption}" Margin="0,0,55,5" DockPanel.Dock="Right" Click="BtnFinishOrder_OnClick" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush= "{TemplateBinding BorderBrush}"
Background= "{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<Button Name="btnTakeIt" Click="BtnTakeIt_OnClick" DataContext="{Binding Items[0]}" Content="{Binding ButtonCaption}" Margin="0,0,20,5" DockPanel.Dock="Right" FontSize="12" BorderThickness="1.5" HorizontalAlignment="Left" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Foreground="#83D744" Background="Transparent" BorderBrush="#83D744" Width="130" Height="40">
<Button.Template>
<ControlTemplate TargetType="Button">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Button.Template>
</Button>
<TextBlock FontWeight="Normal" FontFamily="Verdana" FontSize="20" Height="25" Foreground="#83D744" Text="{Binding Items[0].ProductName}" />
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
public partial class MainWindow : Window
{
private ICollectionView view;
private ObservableCollection<Product> ordersList;
public MainWindow()
{
InitializeComponent();
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
this.WindowState = WindowState.Maximized;
ordersList = new ObservableCollection<Product>()
{
new Product()
{
ProductName = "Prodct",
Quantity = 1,
NumberOfOrder = 100,
IsInProgress = true,
ButtonCaption = "Take it"
},
new Product()
{
ProductName = "Prodct1",
Quantity = 2,
NumberOfOrder = 1000,
ButtonCaption = "Take it"
},
new Product()
{
ProductName = "Prodct2",
Quantity = 3,
NumberOfOrder = 10000,
ButtonCaption = "Take it"
},
new Product()
{
ProductName = "Prodct3",
Quantity = 4,
NumberOfOrder = 100000,
ButtonCaption = "Take it"
},
};
view = CollectionViewSource.GetDefaultView(ordersList);
view.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder"));
DataContext = view;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(20);
timer.Tick += Timer_Tick; ;
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
foreach (var item in ordersList)
{
if (item.IsInProgress)
{
item.ButtonCaption = "Order is Still in progress";
}
}
}
private void BtnFinishOrder_OnClick(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
private void BtnTakeIt_OnClick(object sender, RoutedEventArgs e)
{
Button b = sender as Button;
Product prod = b.DataContext as Product;
b.BorderBrush = null;
prod.ButtonCaption = "Order is in progress";
b.FontSize = 12;
}
}
class Product:INotifyPropertyChanged
{
private string productName;
public string ProductName
{
get { return productName ; }
set
{
productName = value ;
OnPropertyChanged("ProductName");
}
}
private int quantity;
public int Quantity
{
get { return quantity; }
set
{
quantity = value;
OnPropertyChanged("Quantity");
}
}
public int NumberOfOrder { get; set; }
public bool IsInProgress { get; set; }
private string buttonCaption;
public string ButtonCaption
{
get { return buttonCaption; }
set
{
buttonCaption = value;
OnPropertyChanged("ButtonCaption");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I am just wondering if there is a wpf combobox control that can contain multiple columns?
And if not, what XAML I need to use to achieve this?
I am just looking for a basic two column combobox if is possible,
Thanks
Please Refer these links for Multiple Column Combobox which is implemented by editing combox and comboboxitem Default template/style.
1)Link1
2)Link2
Xaml code : Please take a look at commented Trigger IsHighlighted in ComboboxItem style
<Grid>
<ComboBox Height="30" Margin="5" ItemsSource="{Binding}" HorizontalContentAlignment="Stretch">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Margin="2" Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid x:Name="gd" TextElement.Foreground="Black">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Margin="5" Grid.Column="0" Text="{Binding Name}"/>
<TextBlock Margin="5" Grid.Column="1" Text="{Binding State}"/>
<TextBlock Margin="5" Grid.Column="2" Text="{Binding Population}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ComboBoxItem.IsSelected" Value="True">
<Setter TargetName="gd" Property="Background" Value="Gray"></Setter>
<Setter TargetName="gd" Property="TextElement.Foreground" Value="White"></Setter>
</Trigger>
<Trigger Property="ComboBoxItem.IsMouseOver" Value="True">
<Setter TargetName="gd" Property="Background" Value="Blue"></Setter>
<Setter TargetName="gd" Property="TextElement.Foreground" Value="White"></Setter>
</Trigger>
<!--IsHighlighted and IsMouseOver is showing same effect but IsHighlighted is used for showing logical focus( for understanding check using tab key)-->
<!--<Trigger Property="ComboBoxItem.IsHighlighted" Value="True">
<Setter TargetName="gd" Property="Background" Value="Yellow"></Setter>
<Setter TargetName="gd" Property="TextElement.Foreground" Value="Black"></Setter>
</Trigger>-->
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
</Grid>
c# code
public partial class MainWindow : Window
{
private ObservableCollection<City> cities = new ObservableCollection<City>();
public MainWindow()
{
InitializeComponent();
cities.Add(new City() { Name = "Mumbai", State = "Maharashtra", Population = 3000000 });
cities.Add(new City() { Name = "Pune", State = "Maharashtra", Population = 7000000 });
cities.Add(new City() { Name = "Nashik", State = "Maharashtra", Population = 65000 });
cities.Add(new City() { Name = "Aurangabad", State = "Maharashtra", Population = 5000000 });
DataContext = cities;
}
}
class City
{
public string State { get; set; }
public string Name { get; set; }
public int Population { get; set; }
}
Output
Because I found, Heena, that your Xaml does not provide selected dropped down items to be highlighted I modified your code as follows:
Xaml
<ComboBox Name="cbCities" Height="30" Margin="5" HorizontalContentAlignment="Left" HorizontalAlignment="Stretch" ItemsSource="{Binding}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Margin="2" Text="{Binding Name}"/>
<TextBlock Margin="2" Text="{Binding State}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border Name="templateBorder" Padding="2" SnapsToDevicePixels="true">
<ContentPresenter>
<ContentPresenter.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Margin="5" Grid.Column="0" Text="{Binding Name}"/>
<TextBlock Margin="5" Grid.Column="1" Text="{Binding State}"/>
<TextBlock Margin="5" Grid.Column="2" Text="{Binding Population}"/>
</Grid>
</ContentPresenter.Content>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Foreground" Value="{x:Static SystemColors.HighlightTextBrush}"/>
<Setter TargetName="templateBorder" Property="Background" Value="{x:Static SystemColors.HighlightBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
C#
private void Window_Loaded(object sender, RoutedEventArgs e)
{
cities.Add(new City() { Name = "Boston", State = "MA", Population = 3000000 });
cities.Add(new City() { Name = "Los Angeles", State = "CA", Population = 7000000 });
cities.Add(new City() { Name = "Frederick", State = "MD", Population = 65000 });
cities.Add(new City() { Name = "Houston", State = "TX", Population = 5000000 });
cbCities.DataContext = cities;
}
class City
{
public string State { get; set; }
public string Name { get; set; }
public int Population { get; set; }
}
Output
I know im late but this is how you do it in a simplified way, After the DataTemplate tag you can put anything depending on how you want your lay out to look like.
<ComboBox.ItemTemplate>
<DataTemplate >
<StackPanel Orientation="Horizontal">
<TextBlock Foreground="{StaticResource ForegroundMainBrush}"
Margin="5 0"
FontFamily="{StaticResource LatoBold}"
VerticalAlignment="Center">
<Run Text="Code :" />
<Run Text="{Binding ActivityCode,Mode=OneWay}" />
</TextBlock>
<TextBlock Foreground="{StaticResource ForegroundDarkBrush}"
Margin="5 0"
Text="|"
FontFamily="{StaticResource LatoBold}"
VerticalAlignment="Center" />
<TextBlock Foreground="{StaticResource ForegroundMainBrush}"
Margin="5 0"
FontFamily="{StaticResource LatoBold}"
VerticalAlignment="Center">
<Run Text="Rate :" />
<Run Text="{Binding Rate,Mode=OneWay}" />
</TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
Result
Sample Result
Or Use a readonly property in your DataModel as shown on the code below and set your combobox DisplayMemberPath to DisplayMemberPath="CodeRate"
public string ActivityCode { get; set; }
public string Rate { get; set; }
public string CodeRate => string.Format("Code: {0} | Rate:
{1}",ActivityCode,Rate);
I just use StackPanels in mine. Maybe kind of redundant per item, but it got me exactly the solution I wanted without getting too deep into things.
<ComboBox Name="cboTask">
<StackPanel Orientation="Horizontal">
<ComboBoxItem Name="someTask" Content="Doing Some Task" /><Button Name="cmdDetails" Content="..." />
</StackPanel>
</ComboBox>
I have a datagrid in my form which has columns for each of Question Types.
I want that column to be split into two as i want to accept number of compulsory and number of optional questions for each of the question type in the subsequent columns.
I have achieved this in winforms, thanks to stackoverflow.com.
I am trying to achieve the same in WPF
Thanks in advance
I guess this is the DataGrid layout you want.... right?
.------.-----------------.--------.
| | ID Details | |
| Name |-----------------| Status |
| | ID | Passport | |
|------|------|----------|--------|
|X | 123 | E567868 | Present|
|Y | 236 | 7875678 | Absent |
'------'------'----------'--------'
WPF datagrid doesnt support this readily. But you can do some stretchy coding. The code like below can split the headers. You need to take caution that ...
When the split columns are reordered (DataGrid.ColumnReordered
event), all the sibling columns under their common parent header should be
moved, together. I am leaving that code to you.
Have some custom styles for DataGridHeaders
<Style TargetType="{x:Type Primitives:DataGridColumnHeader}"
x:Key="SplitHeaderStyle">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Primitives:DataGridColumnHeader}">
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Bottom">
<Controls:DataGridHeaderBorder
SortDirection="{TemplateBinding SortDirection}"
IsHovered="{TemplateBinding IsMouseOver}"
IsPressed="{TemplateBinding IsPressed}"
IsClickable="{TemplateBinding CanUserSort}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding ="{TemplateBinding Padding}"
SeparatorVisibility="{TemplateBinding SeparatorVisibility}"
SeparatorBrush="{TemplateBinding SeparatorBrush}">
<ContentPresenter
Content="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Content[0]}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="Center"/>
</Controls:DataGridHeaderBorder>
<Thumb x:Name="PART_LeftHeaderGripper"
HorizontalAlignment="Left"
Style="{StaticResource ColumnHeaderGripperStyle}"/>
<Thumb x:Name="PART_RightHeaderGripper"
HorizontalAlignment="Right"
Style="{StaticResource ColumnHeaderGripperStyle}"/>
</Grid>
<Grid DockPanel.Dock="Top">
<Controls:DataGridHeaderBorder
HorizontalAlignment="Stretch"
IsClickable="False"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding SeparatorBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding ="{TemplateBinding Padding}"
SeparatorVisibility="{TemplateBinding Tag}"
SeparatorBrush="{TemplateBinding SeparatorBrush}">
<ContentPresenter
Content="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=Content[1]}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="-8,2,-10,2"/>
</Controls:DataGridHeaderBorder>
<Thumb x:Name="PART_LeftSplitHeaderGripper"
HorizontalAlignment="Right"
Visibility="{TemplateBinding Tag}"
Style="{StaticResource ColumnHeaderGripperStyle}"/>
</Grid>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Primitives:DataGridColumnHeader}"
BasedOn="{StaticResource SplitHeaderStyle}"
x:Key="SplitHeaderLeftStyle">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Tag" Value="{x:Static Visibility.Visible}"/>
</Style>
<Style TargetType="{x:Type Primitives:DataGridColumnHeader}"
BasedOn="{StaticResource SplitHeaderStyle}"
x:Key="SplitHeaderRightStyle">
<Setter Property="HorizontalContentAlignment" Value="Right"/>
<Setter Property="Tag" Value="{x:Static Visibility.Collapsed}"/>
</Style>
Have columns arranged like this...
<Controls:DataGrid.Columns>
<Controls:DataGridTextColumn
Header="Name"
Binding="{Binding Name}"/>
<Controls:DataGridTextColumn
Binding="{Binding ID}"
HeaderStyle="{StaticResource SplitHeaderRightStyle}">
<Controls:DataGridTextColumn.Header>
<x:ArrayExtension Type="System:String">
<System:String>ID</System:String>
<System:String>ID De</System:String>
</x:ArrayExtension>
</Controls:DataGridTextColumn.Header>
</Controls:DataGridTextColumn>
<Controls:DataGridTextColumn
Binding="{Binding Passport}"
HeaderStyle="{StaticResource SplitHeaderLeftStyle}">
<Controls:DataGridTextColumn.Header>
<x:ArrayExtension Type="System:String">
<System:String>Passport</System:String>
<System:String>tails</System:String>
</x:ArrayExtension>
</Controls:DataGridTextColumn.Header>
</Controls:DataGridTextColumn>
<Controls:DataGridTextColumn
Header="Status"
Binding="{Binding Status}"/>
</Controls:DataGrid.Columns>
So basically you use the same default header layout of DataGrid but hack it in a way that two headers look like they are joined together.
C#
Name your DataGrid e.g. x:Name="MyDataGrid".
Keep all the styles in XAML in <DataGrid.Resources ..> tag. Make sure that they have x:Key set. e.g. x:Key="SplitHeaderLeftStyle" & x:Key="SplitHeaderRightStyle"
<DataGrid x:Name="MyDataGrid">
<DataGrid.Resources>
<Style
TargetType="{x:Type Primitives:DataGridColumnHeader}"
x:Key="SplitHeaderStyle" .../>
<Style x:Key="SplitHeaderLeftStyle"
BasedOn="{StaticResource SplitHeaderStyle}".../>
<Style x:Key="SplitHeaderRightStyle"
BasedOn="{StaticResource SplitHeaderStyle}" .../>
</DataGrid.Resources>
...
</DataGrid>
in your C# code when you add columns, set the styles by their Key.
var dgIDColumn
= new DataGridTextColumn()
{
Header = new string[] { "ID", "ID Det" },
Binding = new Binding() { Path = new PropertyPath("ID") },
HeaderStyle = MyDataGrid.FindResource("SplitHeaderRightStyle") as Style;
};
MyDataGrid.Columns.Add(dgIDColumn);
var dgPassportColumn
= new DataGridTextColumn()
{
Header = new string[] { "Passport", "ails" },
Binding = new Binding() { Path = new PropertyPath("Passport") },
HeaderStyle = MyDataGrid.FindResource("SplitHeaderLeftStyle") as Style;
};
MyDataGrid.Columns.Add(dgPassportColumn);
<DataGrid ItemsSource="{Binding PeopleList}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type local:Person}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="10"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="Question1" Grid.ColumnSpan="2"/>
<TextBlock Text="Compulsory" Grid.Row="1"/>
<TextBlock Text="Optional Q" Grid.Row="1" Grid.Column="2"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate DataType="{x:Type local:Person}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="65"/>
<ColumnDefinition/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Question.Col1}"/>
<TextBlock Text="{Binding Question.Col2}" Grid.Column="2"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
You can modify the Row/Column/ColumnSpan/RowSpan in DataTriggers of ItemsControl.ItemContainerStyle to your liking.
<ItemsControl ItemsSource="{Binding Path=Cells}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid
local:GridHelpers.ColumnCount="{Binding NumOfColumns}"
local:GridHelpers.AutoColumns="0,1"
local:GridHelpers.RowCount="{Binding NumOfRows}"
local:GridHelpers.AutoRows="0,1">
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Grid.Row" Value="{Binding Path=RowIndex}"/>
<Setter Property="Grid.Column" Value="{Binding Path=ColumnIndex}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CellType}" Value="BaseCell">
<Setter Property="ContentTemplate" Value="{StaticResource BaseCell}"/>
<Setter Property="Grid.ColumnSpan" Value="{Binding Path=ColumnSpan}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=CellType}" Value="CornerHeader">
<Setter Property="ContentTemplate" Value="{StaticResource CornerHeader}"/>
<Setter Property="Grid.RowSpan" Value="2"/>
<Setter Property="Grid.ColumnSpan" Value="2"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=CellType}" Value="PersonNameCell">
<Setter Property="ContentTemplate" Value="{StaticResource PersonNameCell}"/>
</DataTrigger>
...
</Style.Triggers>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
I've added AutoColumns property to GridHelper class which is explained in this link
#region AutoColumns Property
/// <summary>
/// Makes the specified Column's Width equal to Auto.
/// Can set on multiple Columns
/// </summary>
public static readonly DependencyProperty AutoColumnsProperty =
DependencyProperty.RegisterAttached(
"AutoColumns", typeof(string), typeof(GridHelpers),
new PropertyMetadata(string.Empty, AutoColumnsChanged));
// Get
public static string GetAutoColumns(DependencyObject obj)
{
return (string)obj.GetValue(AutoColumnsProperty);
}
// Set
public static void SetAutoColumns(DependencyObject obj, string value)
{
obj.SetValue(AutoColumnsProperty, value);
}
// Change Event - Makes specified Column's Width equal to Auto
public static void AutoColumnsChanged(
DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (!(obj is Grid) || string.IsNullOrEmpty(e.NewValue.ToString()))
return;
SetAutoColumns((Grid)obj);
}
private static void SetAutoColumns(Grid grid)
{
string[] autoColumns = GetAutoColumns(grid).Split(',');
for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
{
if (autoColumns.Contains(i.ToString()))
grid.ColumnDefinitions[i].Width = GridLength.Auto;
}
}
private static void SetAutoRows(Grid grid)
{
string[] autoRows = GetAutoRows(grid).Split(',');
for (int i = 0; i < grid.RowDefinitions.Count; i++)
{
if (autoRows.Contains(i.ToString()))
grid.RowDefinitions[i].Height = GridLength.Auto;
}
}
#endregion
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.
I'm creating my own control, I'm wondering the best way to bind the textblock text property below, I have the contentpresenter set to bind to content, how can I set the textblock text value?
<Style TargetType="ctrl:Selection">
<Setter Property="Width" Value="200" />
<Setter Property="Height" Value="100" />
<Setter Property="Background" Value="Lavender" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ctrl:Selection">
<Grid x:Name="RootElement">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Fill="{TemplateBinding Background}" Stroke="black" RadiusX="16" RadiusY="16" />
<TextBlock Grid.Row="0" Text="How do i bind this?" x:Name="HeaderText" HorizontalAlignment="Center" VerticalAlignment="Center" />
<ContentPresenter Grid.Row="1" x:Name="BodyContent" Content="{TemplateBinding Content}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
public class Selection : ContentControl {
public Selection() {
this.DefaultStyleKey = typeof(Selection);
}
}
You can register a property in your control class, something like this...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(Selection), new PropertyMetadata(""));
public string Text {
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}