DataGrid Styles - lucyberryhub/WPF.Tutorial GitHub Wiki
In this tutorial, we're going to walk you through creating adorable, cherry-themed styles and templates for a DataGrid
. Weβll also be working with dynamic resources, like cherry-colored text and berry-filled backgrounds, in a WPF UserControl
. π
Letβs start by defining some necessary resources and then dive into customizing your DataGrid
for the most delightful experience! π
Weβll first define some cherry-berry-themed resources inside the UserControl.Resources
. This will include a converter for setting the maximum height dynamically, some styles for text alignment, and cute trigger-based styles for text color and tooltips.
<UserControl.Resources>
<!-- Cherry-Berry Converter for DataGrid Height -->
<local:HeightToMaxDataGridHeightConverter x:Key="HeightToMaxDataGridHeightConverter"/>
<!-- Style for Centered TextBlock (Berry-themed) -->
<Style x:Key="centeredCherryTextStyle" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<!-- Foreground Style with Berry Trigger for TextBlock -->
<Style x:Key="berryForegroundTextStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="{DynamicResource cor_brush_ThemeForeground}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ComboValue}" Value="{StaticResource str_sikaku}">
<Setter Property="Foreground" Value="Transparent"/>
<Setter Property="ToolTip" Value="This text is berry read-only!" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
Explanation:
-
HeightToMaxDataGridHeightConverter: A converter that dynamically adjusts the height of the
DataGrid
. π -
centeredCherryTextStyle: Centers the text inside a
TextBlock
, with a subtle cherry-berry feel. π - berryForegroundTextStyle: Changes the text color to transparent for certain conditions and adds a cute tooltip for read-only text. πΈ
Weβll now create a helper class called TemplateHelper
, where we will add methods for styling the ComboBox
, creating DataTemplates
, and moreβjust like weβre styling a cherry-berry smoothie! π
public static class CherryBerryTemplateHelper
{
public static Style CreateComboBoxBerryStyle(SelectionChangedEventHandler selectionChangedEventHandler)
{
var style = new Style(typeof(ComboBox));
// Set the event handler for SelectionChanged (Berries of Selection!)
style.Setters.Add(new EventSetter(ComboBox.SelectionChangedEvent, selectionChangedEventHandler));
// Center the content like a berry in a bowl (super cute!)
style.Setters.Add(new Setter(ComboBox.HorizontalContentAlignmentProperty, HorizontalAlignment.Center));
style.Setters.Add(new Setter(ComboBox.VerticalContentAlignmentProperty, VerticalAlignment.Center));
// Style the items in the ComboBox's drop-down list with berry backgrounds
style.Setters.Add(new Setter(ComboBox.ItemContainerStyleProperty, new Style(typeof(ComboBoxItem))
{
Setters =
{
// Set the background and foreground of the ComboBoxItem (Berry-licious!)
new Setter(ComboBoxItem.BackgroundProperty, Brushes.Pink),
new Setter(ComboBoxItem.ForegroundProperty, Brushes.Black)
},
// Triggers to style ComboBoxItem when selected or hovered (Berry love triggers!)
Triggers =
{
new DataTrigger
{
// When the item is selected (cherry-picked!)
Binding = new Binding("IsSelected"),
Value = true,
Setters =
{
new Setter(ComboBoxItem.BackgroundProperty, Brushes.DarkRed),
new Setter(ComboBoxItem.ForegroundProperty, Brushes.White)
}
},
new Trigger
{
// When the mouse is over the item (berry-hovered!)
Property = ComboBoxItem.IsMouseOverProperty,
Value = true,
Setters =
{
new Setter(ComboBoxItem.BackgroundProperty, Brushes.LightPink),
new Setter(ComboBoxItem.ForegroundProperty, Brushes.Black)
}
}
}
}));
return style;
}
public static DataTemplate CreateBerryTextTemplate(string bindingProperty, bool isBerryRelated = false, ResourceDictionary resources = null)
{
var dataTemplate = new DataTemplate(typeof(TextBlock));
var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));
textBlockFactory.SetBinding(TextBlock.TextProperty, new Binding(bindingProperty) { Mode = BindingMode.OneWay });
// Apply Cherry-Berry Text Styles from resources
var centeredBerryStyle = (Style)resources["centeredCherryTextStyle"];
var berryForegroundStyle = (Style)resources["berryForegroundTextStyle"];
// Create a new Style based on centeredBerryStyle
var combinedBerryStyle = new Style(typeof(TextBlock), centeredBerryStyle);
// Add foreground style from berryForegroundStyle to combinedBerryStyle
foreach (var setter in berryForegroundStyle.Setters)
{
combinedBerryStyle.Setters.Add(setter);
}
// Add triggers from berryForegroundStyle to combinedBerryStyle
foreach (var trigger in berryForegroundStyle.Triggers)
{
combinedBerryStyle.Triggers.Add(trigger);
}
// Set the style to TextBlock
textBlockFactory.SetValue(TextBlock.StyleProperty, centeredBerryStyle);
// If the text is berry-related, apply the combined style
if (isBerryRelated)
{
textBlockFactory.SetValue(TextBlock.StyleProperty, combinedBerryStyle);
}
dataTemplate.VisualTree = textBlockFactory;
return dataTemplate;
}
public static DataTemplate CreateEditingBerryTemplate(string bindingProperty, string berryInfo = null)
{
var dataTemplate = new DataTemplate(typeof(TextBox));
var textBoxFactory = new FrameworkElementFactory(typeof(TextBox));
textBoxFactory.SetBinding(TextBox.TextProperty, new Binding(bindingProperty) { Mode = BindingMode.TwoWay });
textBoxFactory.SetValue(TextBox.VerticalContentAlignmentProperty, VerticalAlignment.Center);
textBoxFactory.SetValue(TextBox.HorizontalContentAlignmentProperty, HorizontalAlignment.Center);
// Attach a KeyUp handler for berry editing, if necessary
if (berryInfo != null)
{
// Save the berry information in the Tag property
textBoxFactory.SetValue(FrameworkElement.TagProperty, berryInfo);
textBoxFactory.AddHandler(TextBox.KeyUpEvent, new System.Windows.Input.KeyEventHandler(BerryTextBox_KeyUp));
}
dataTemplate.VisualTree = textBoxFactory;
return dataTemplate;
}
// KeyUp event handler to display berry info (super cute)
private static void BerryTextBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
if (sender is TextBox textBox && textBox.IsFocused)
{
string berryInfo = textBox.Tag as string;
if (berryInfo != null)
{
textBox.Text = "Berry-licious!"; // Reset value (cute reset!)
MessageBox.Show($"{berryInfo} is a berry-related item! No more changes.", "Berry Warning", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
}
}
Now that weβve set up all the cute styles and templates, letβs apply them to your DataGrid
. π Hereβs how to define a DataGrid
in your UserControl
that uses these new cherry-berry styles.
<DataGrid x:Name="berryDataGrid" AutoGenerateColumns="False" Height="300" Width="500">
<!-- Apply the berry cell templates for each column -->
<DataGrid.Columns>
<DataGridTextColumn Header="Berry Name" Binding="{Binding BerryName}" CellTemplate="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=Resources[centeredCherryTextStyle]}"/>
<DataGridTextColumn Header="Berry Color" Binding="{Binding BerryColor}" CellTemplate="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=Resources[berryForegroundTextStyle]}"/>
<DataGridTemplateColumn Header="Berry Info" CellTemplate="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=Resources[CreateBerryTextTemplate]}" />
</DataGrid.Columns>
</DataGrid>
Letβs finish by hooking up some adorable behavior, where a user can interact with the DataGrid
. Here's a little snippet of how you might wire it up in your UserControl.xaml.cs
.
public partial class BerryBerryUserControl : UserControl
{
public BerryBerryUserControl()
{
InitializeComponent();
// Example collection of berry items
var berryItems = new List<BerryItem>
{
new BerryItem { BerryName = "Strawberry", BerryColor = "Red" },
new BerryItem { BerryName = "Blueberry", BerryColor = "Blue" }
};
// Set the data source for the DataGrid
berryDataGrid.ItemsSource = berryItems;
}
}
// Define a simple BerryItem class
public class BerryItem
{
public string BerryName { get; set; }
public string BerryColor { get; set; }
}
And that's how you can create a super cute, cherry-berry-themed DataGrid in WPF! π You learned how to create and apply cherry-berry-inspired styles and templates for your DataGrid
, making it not only functional but also super adorable and girly. π
Letβs summarize:
- Created Cherry-Berry Styles π
-
Used
DataTemplates
for custom cell appearances π - Hooked up interactive templates for textboxes π