How do I assign a defined style in Window.Resources to the ToolTip style for my DataGridTemplateColumn?
<Style x:Key="StatusColumn" TargetType="ToolTip">
<Setter Property="Content">
<Setter.Value>
<TextBlock>
<Run Text="Black - Inactive"/>
<LineBreak/>
<Run Text="Green - Active"/>
<LineBreak/>
<Run Text="Yellow - Update"/>
</TextBlock>
</Setter.Value>
</Setter>
</Style>
I am trying in this way:
<DataGridTemplateColumn Width="50" Header="Status" IsReadOnly="True" >
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="ToolTip" >
?
</Setter>
</Style>
</DataGridTemplateColumn.CellStyle>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Rectangle Width="20" Height="20" Fill="{Binding Brush}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
You can add a ToolTip as setter value and set its Style property using StaticResource.
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip Style="{StaticResource StatusColumn}"/>
</Setter.Value>
</Setter>
</Style>
</DataGridTemplateColumn.CellStyle>
Related
So i have a DataGridColumn that has it's own style as StaticResource:
<DataGridTemplateColumn Header="Name"
HeaderStyle="{StaticResource PropertiesHeaders}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<!--some code>-->
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
And a style:
<Style TargetType="{x:Type DataGridColumnHeader}" x:Key="PropertiesHeaders">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<TextBlock Background="#FF137FDC"
Foreground="White"
FontFamily="Bahnschrift SemiBold Condensed"
FontWeight="Bold"
FontSize="16"
Padding="5"
TextAlignment="Center"
Text{???}/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How to correctly bind the "Text" property of TextBlock so that in the header table it bears the name of the "Header" property in DataGridTemplateColumn?
I'm searching how to change the background color of my WPF Listbox, nothing worked... I don't want to change the background of the Item Template, but of the ListBox himself.
I tried the differents solutions answered here Answers
Here is my Listbox :
<ListBox Name="myListBox" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="myListBox_SelectionChanged" Background="#FFC3DDF7" Margin="0,0,0,10">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Value.IsOk}" Value="True">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Width="200">
<TextBlock FontSize="10" FontWeight="Bold" VerticalAlignment="Center" Text="{Binding Path=Key}" />
<TextBlock FontSize="10" VerticalAlignment="Center" TextWrapping="Wrap">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1} {2}">
<Binding Path="Value.TextA" />
<Binding Path="Value.TextB" />
<Binding Path="Value.TextC" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Maybe the item template is on the foreground ?
Tried these codes :
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Blue"/>
</Style.Resources>
</Style>
and
<ListBox>
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Style>
</ListBox>
Not working. The down right corner, between the two scrollbars, became blue... But that's all !
The reason why your linked answer does not work is because you have the background of the listbox set to #FFC3DDF7 on the element itself. If you wish to change the initial background color of your listbox this would need to be moved into the style. If you do not move this then the rule for "closest" defined value would be the one on the element itself and the style can't override this.
<ListBox Name="myListBox" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionChanged="myListBox_SelectionChanged" Margin="0,0,0,10">
<ListBox.Style>
<Style TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="#FFC3DDF7"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="LightGray" />
<Setter Property="Background" Value="LightGray" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Style>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Value.IsOk}" Value="True">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StackPanel Width="200">
<TextBlock FontSize="10" FontWeight="Bold" VerticalAlignment="Center" Text="{Binding Path=Key}" />
<TextBlock FontSize="10" VerticalAlignment="Center" TextWrapping="Wrap">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1} {2}">
<Binding Path="Value.TextA" />
<Binding Path="Value.TextB" />
<Binding Path="Value.TextC" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
As Anthony pointed out, your style trigger will never set the Background of your ListBox because you have set a local value. It's called "Dependency Property Precedence". Take a look at this link: https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-value-precedence.
"Local" values have higher precedence over "style trigger" values. However, "style trigger" values have higher precedence over "style setter" values. This means that if you want to have an initial value for the property and change it based on a trigger, just set it in the style initially, instead of setting it locally like your code does.
First off all - this msdn link ListBox Styles and Templates will help you the most. You can check this way - what applies where in a ListBox and a ListBoxItem.
If you check the Style of the ListBoxItem you will see that the ContentPresenter gets no Foreground applied.
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter x:Name="contentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"/><!-- No foreground gets applied. -->
<Rectangle x:Name="FocusVisualElement" Stroke="#FF6DBDD1" StrokeThickness="1" Visibility="Collapsed" RadiusX="1" RadiusY="1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Anyway here is your solution:
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Width="200">
<TextBlock VerticalAlignment="Center"
FontSize="10"
TextWrapping="Wrap">
<Run FontWeight="Bold" Text="{Binding Path=Key}" />
<LineBreak />
<Run>
<Run.Text>
<MultiBinding StringFormat="{}{0} {1} {2}">
<Binding Path="Value.TextA" />
<Binding Path="Value.TextB" />
<Binding Path="Value.TextC" />
</MultiBinding>
</Run.Text>
</Run>
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsOk}" Value="True" >
<Setter Property="Foreground" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
The TextBlock now listens to isOk and will applys the Foreground.
I am working with WPF application, and I grouped my items using <DataGrid.GroupStyle>, I am wondering how can I set header text when group is collapsed. I'm loading orders into that grouped grid, and when I collapse specific group I would like to see something like Order : number of order, because of easier orient. Right now I am seeing only number of order, but how could I add text to:
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" /> //+ some text
</DockPanel>
(Also, after I added <DataGrid.Columns> because I want to add my columns manualy suddenly vertical slider appear on screen even if there is no more items left or right and it looks bad and annoying, how could I remove that slider, I want to keep my datagrid columns because I want to style them as I want, but I don't want to see that slider :/ ?)
Here is my code:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*" />
</Grid.ColumnDefinitions>
<DataGrid Grid.Column="0" RowHeaderWidth="0" CanUserAddRows="False" AutoGenerateColumns="False" x:Name="datagrid1" Margin="10,150,8,50" Background="Transparent" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" ItemsSource="{Binding}">
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="Black"/>
<Setter Property="Opacity" Value="0.5"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Height" Value="50"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ProductName}" Header="Title" MinWidth="50" FontSize="16" FontFamily="Verdana" />
<DataGridTextColumn Binding="{Binding Quantity}" Header="Quantity" MinWidth="30" FontSize="16" FontFamily="Verdana" />
<DataGridTextColumn Binding="{Binding NumberOfOrder}" Header="Order number" MinWidth="30" FontSize="16" FontFamily="Verdana" />
<DataGridTextColumn Binding="{Binding User}" Header="User" Width="*" FontSize="16" 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">
<Expander.Header>
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" /> //I am wondering what does this line mean?
</DockPanel>
</Expander.Header>
<Expander.Content>
<ItemsPresenter />
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
P.S ScreenShot of vertical slider # bottom of my datagrid
We need a Trigger here as shown below, and an IValueConverter to find number of items in a group :
<Expander.Style>
<Style TargetType="Expander">
<Style.Triggers>
<Trigger Property="IsExpanded" Value="True">
<Setter Property="Header">
<Setter.Value>
<DockPanel>
<TextBlock FontWeight="Bold" Text="{Binding Name}" />
</DockPanel>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsExpanded" Value="False">
<Setter Property="Header">
<Setter.Value>
<DockPanel>
<TextBlock FontWeight="Bold">
<TextBlock.Inlines>
<Run Text="{Binding Name}"/>
<Run Text=" ( "/>
<Run Text="{Binding Name, Converter={StaticResource ItemCountCnvKey}}" />
<Run Text=" ) "/>
</TextBlock.Inlines>
</TextBlock>
</DockPanel>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Expander.Style>
ItemCountConverter
public class ItemCountConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
CollectionViewGroup group = (CollectionViewGroup)value;
ReadOnlyObservableCollection<object> items = group.Items;
return items.Count;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
I have a TreeView to which I bind a ObservableCollection where TreeView inherits TreeViewItem.
I want to style the header of the tree view to have a image in front of each header. I setted the header to the ItemContainerStyle but it did not chnage its layout. However it works for the ContextMenu.
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="ToolTip" Value="{Binding ID, Mode=TwoWay}"/>
<Setter Property="Header">
<Setter.Value>
<StackPanel Orientation="Horizontal">
<Image Source="Images/Icons/Plus-48.png" Height="10" Width="10" />
<TextBlock Text="{Binding MachinePartName}" Margin="0,0,4,0" />
</StackPanel>
</Setter.Value>
</Setter>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Add" Command="{Binding AddMachinePart_Command}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</TreeView.ItemContainerStyle>
You need to use HeaderTemplate instead:
<Setter Property="Header"
Value="{Binding }" />
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="Images/Icons/Plus-48.png"
Height="10"
Width="10" />
<TextBlock Text="{Binding MachinePartName}"
Margin="0,0,4,0" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
Don't forget to bind Header property.
In my C# / WPF application, I have a Datagrid with several DataGridTextColumn column using both text wrapping and a tooltip.
I could write each column like this (and this works fine):
<DataGridTextColumn Header="Name" Binding="{Binding Name}">
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="ToolTip" Value="Some tooltip text" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
But I would like to define a common style that can set both the wrapping and the tooltip text, knowing that the tooltip text will be different for each column. The purpose is to avoid code redundancy and make it clearer.
So far, here's my style:
<Window.Resources>
<Style x:Key="WrapStyle" TargetType="{x:Type DataGridCell}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Text}" TextWrapping="Wrap">
<TextBox.ToolTip>
<ToolTip>
<ToolTip.Content>
<TextBlock Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Tooltip}" />
</ToolTip.Content>
</ToolTip>
</TextBox.ToolTip>
</TextBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</Window.Resources>
And my column:
<DataGridTextColumn Header="Name" Binding="{Binding Name}" CellStyle="{StaticResource WrapStyle}" />
The problem is that I can't specify a tooltip to pass to the style. Is there a way to do it without writing 5 lines of DataGridTextColumn.CellStyle for each column?
Thanks
Modify the style to -
<Window.Resources>
<Style x:Key="WrapStyle" TargetType="DataGridCell">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Text}" TextWrapping="Wrap">
<TextBox.ToolTip>
<ToolTip>
<ToolTip.Content>
<TextBlock Text="{Binding Path=Tooltip}"></TextBlock>
</ToolTip.Content>
</ToolTip>
</TextBox.ToolTip>
</TextBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</Window.Resources>