i am trying to change the style of my button based on its own dependency property. i cant seem to figure out why this is not working. it has got to do with the enum and how to bind it. im am new to WPF and ive been searching forever. please help!
the relevant code. first my button class:
public class AmmoType
{
public enum ammoType { RFS, RFD, RFC, EMPTY }
}
public class DLSButton : Button
{
public static readonly DependencyProperty AmmoTypeProperty;
public AmmoType.ammoType ammoTypeEnum
{
get
{
return (AmmoType.ammoType)GetValue(DLSButton.AmmoTypeProperty);
}
set
{
SetValue(DLSButton.AmmoTypeProperty, value);
}
}
static DLSButton()
{
DLSButton.AmmoTypeProperty = DependencyProperty.Register("ammoTypeEnum", typeof(AmmoType.ammoType), typeof(DLSButton), new FrameworkPropertyMetadata(AmmoType.ammoType.EMPTY));
}
}
my application Ressources (App.xml):
<Application.Resources>
<Style TargetType="{x:Type local:DLSButton}" x:Key="DLSAmmo">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Background" Value="LightGray"/>
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="Margin" Value="1,1,1,1" />
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Viewbox StretchDirection="Both" >
<TextBlock FontWeight="Bold" TextWrapping="Wrap">DLS</TextBlock>
</Viewbox>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=AmmoType+ammoType}" Value="{x:Static my:AmmoType+ammoType.EMPTY}">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Background" Value="Red"/>
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="Margin" Value="1,1,1,1" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Viewbox StretchDirection="Both" >
<TextBlock FontWeight="Bold" TextWrapping="Wrap">N/A</TextBlock>
</Viewbox>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=ammoTypeEnum}" Value="RFD">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Background" Value="Green"/>
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="Margin" Value="1,1,1,1" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Viewbox StretchDirection="Both" >
<TextBlock FontWeight="Bold" TextWrapping="Wrap">RFD</TextBlock>
</Viewbox>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=ammoTypeEnum}" Value="{x:Static local:AmmoType+ammoType.RFS}">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Background" Value="Green"/>
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="Margin" Value="1,1,1,1" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Viewbox StretchDirection="Both" >
<TextBlock FontWeight="Bold" TextWrapping="Wrap">RFS</TextBlock>
</Viewbox>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=ammoTypeEnum}" Value="{x:Static local:AmmoType+ammoType.RFC}">
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Background" Value="Green"/>
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="Margin" Value="1,1,1,1" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Viewbox StretchDirection="Both" >
<TextBlock FontWeight="Bold" TextWrapping="Wrap">RFC</TextBlock>
</Viewbox>
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Application.Resources>
my XAML where i insert my button:
<local:DLSButton ammoTypeEnum="EMPTY" x:Name="buttonDLS1" Style="{StaticResource DLSAmmo}">
</local:DLSButton>
no errors are shown in error list. but when i build the solution a messagebox tells me that: "the property value is not valid"
and as you can see in the different 'DataTriggers' i have tried different things with binding. still no errors. and still no style changing...
After some fiddling, I remembered that I hadn't set the data context when I copy/pasta'd your code. That did the trick after fixing some of the datatrigger bindings and values to the values you already had working. Here's what I changed, and it works on my computer:
App.xaml
// so we can see the bg change, but the text changed without it
<Setter Property="IsEnabled" Value="True"/>
...
// for each of the datatriggers
<DataTrigger Binding="{Binding Path=ammoTypeEnum}"
Value="{x:Static local:AmmoType+ammoType.XXX}">
DLSButton.cs
// this should be obvious
public partial class DLSButton : Button
{
public DLSButton()
{
InitializeComponent();
DataContext = this;
}
...
}
Related
I'm trying to center the content of my ListBoxItem vertically and horizontally but I can't get it to work.
My style template :
<Style x:Key="myListBoxItem" TargetType="ListBoxItem">
<Style.Resources>
<Style TargetType="Border">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="2" Direction="90" BlurRadius="4" Color="Black" Opacity="0.25"/>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#fe3f3f"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="DemiBold"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True"/>
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Background" Value="#e9e9e9"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Cursor" Value="Hand"/>
</MultiTrigger.Setters>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Width" Value="160"/>
<Setter Property="Height" Value="75"/>
<Setter Property="Background" Value="White"/>
<Setter Property="FontSize" Value="19"/>
</Style>
Here is how I apply this style : I have a simple ListBox in my XAML, and I append ListBoxItems to it in code-behind. I set the ResourceReference of each ListBoxItem to my style this way :
foreach (var equipment in listEquipments)
{
var lbi = new ListBoxItem();
lbi.Content = equipment.Name;
lbi.SetResourceReference(StyleProperty, "myListBoxItem");
ListBox_Equipments.Items.Add(lbi);
}
I've tried to set the HorizontalContentAlignment and HorizontalContentAlignment of the ListBoxItem (through the style template) to Center, as well as the HorizontalAlignment and VerticalAlignment, but nothing succeeded. I thought it might have to do with my style template.
I also tried some ItemTemplates such as :
<ListBox HorizontalContentAlignment="Center">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text}" FontSize="72"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
No luck so far.
An ItemTemplate is not applied to a ListBoxItem.
Set or bind the ItemsSource of the ListBox to your listEquipments:
ListBox_Equipments.ItemsSource = listEquipments;
...and set the ItemContainerStyle of the ListBox to your custom Style:
<ListBox x:Name="ListBox_Equipments"
ItemContainerStyle="{StaticResource myListBoxItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm using CheckBox and I want to change the color to gray of the CheckBox that are disabled with IsEnabled = false .
Is posible to change the color in XAML? If is not possible, how can I make it possible in code?
My XAML:
<Style x:Key="CheckBoxStyles" TargetType="CheckBox">
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="VerticalOptions" Value="Center" />
<Setter Property="Color" Value="{StaticResource checkBoxColor}" />
</Style>
<CheckBox
x:Name="FirstCB"
IsChecked="{Binding CheckedFirstCB, Mode=TwoWay}"
Style="{StaticResource CheckBoxStyles}" />
<CheckBox
x:Name="SecondCB"
IsChecked="{Binding CheckedSecondCB, Mode=TwoWay}"
Style="{StaticResource CheckBoxStyles}" />
Code:
FirstCB.IsEnabled = true;
SecondCB.IsEnabled = false;
As #RenéVogt mentioned in his comment you can achieve that with a style triggers:
<Style x:Key="CheckBoxStyles" TargetType="CheckBox">
<Setter Property="HorizontalOptions" Value="Center"/>
<Setter Property="VerticalOptions" Value="Center"/>
<Setter Property="Color" Value="{StaticResource checkBoxColor}"/>
<Style.Triggers>
<Trigger TargetType="CheckBox" Property="IsEnabled" Value="False">
<Setter Property="Color" Value="Gray"/>
</Trigger>
</Style.Triggers>
</Style>
Ok, i know my question might be super dumb- but i couldn't find the solution my self- so here i am- asking your help:
in wpf i have a DataGrid with different styles.
now, i need to set the tooltip max width.
this is my DataGridCell style:
<Style TargetType="DataGridCell" x:Key="MyDataGridCellStyle">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" />
<EventSetter Event="PreviewTextInput" Handler="DataGridCell_PreviewTextInput" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="Background" Value="White" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/>
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},Path=Content.Text}"/>
</Style>
how do i add to the tooltip the max width style?
Try this please
Keep this code
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self},Path=Content.Text}"/>
and add this to your datagrid
<DataGrid.Resources>
<Style TargetType="ToolTip">
<Setter Property="MaxWidth" Value="20" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<ContentPresenter Content="{TemplateBinding Content}" >
<ContentPresenter.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.Resources>
Is what you tried to put your tooltip in a textblock
<Setter Property="ToolTip">
<Setter.Value>
<TextBlock MaxWidth="..." TextWrapping="Wrap" Text ="{Binding RelativeSource={RelativeSource Self},Path=Content.Text}"/>
</Setter.Value>
</Setter>
I have the following Column in my datagrid :
<DataGridTemplateColumn CanUserReorder="False" CanUserResize="True" Header="">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate />
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellStyle>
<Style TargetType="DataGridCell" BasedOn="{StaticResource DatagridCellHyperlinkStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Padding="{TemplateBinding Padding}" VerticalAlignment="Center">
<TextBlock Width="Auto" Height="Auto" TextTrimming="CharacterEllipsis">
<Hyperlink>
<InlineUIContainer TextDecorations="{Binding Path=TextDecorations, RelativeSource={RelativeSource AncestorType=TextBlock}}" Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType=TextBlock}}">
<ContentPresenter Width="Auto" Height="Auto" Content="{Binding DataContext.Value, RelativeSource={RelativeSource AncestorType=DataGridRow}}"/>
</InlineUIContainer>
<Hyperlink.Style>
<Style TargetType="Hyperlink" BasedOn="{StaticResource HyperlinkStyle}">
<EventSetter Event="Hyperlink.Click" Handler="Click" />
</Style>
</Hyperlink.Style>
</Hyperlink>
</TextBlock>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGridTemplateColumn.CellStyle>
</DataGridTemplateColumn>
The hyperlink works perfectly (with my style also) but the text trimming doesn't work. How can I change my code to make it work ?
The 2 styles attached :
<Style x:Key="DatagridCellHyperlinkStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Padding" Value="5" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontFamily" Value="Helvetica" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Foreground" Value="{StaticResource CouleurBouton}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource ResourceKey=CouleurBouton}"/>
<Setter Property="Foreground" Value="{StaticResource ResourceKey=CouleurFond}" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource ResourceKey=CouleurBouton}"/>
<Setter Property="Foreground" Value="{StaticResource ResourceKey=CouleurFond}" />
</Trigger>
<DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Background" Value="{StaticResource ResourceKey=CouleurBoutonHover}"/>
<Setter Property="Foreground" Value="{StaticResource ResourceKey=CouleurTexteBoutonHover}" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="HyperlinkStyle" TargetType="{x:Type Hyperlink}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{DynamicResource CouleurBoutonPressed}" />
</Trigger>
</Style.Triggers>
<Setter Property="Foreground" Value="{DynamicResource CouleurBouton}" />
<Setter Property="TextBlock.TextDecorations" Value="{x:Null}" />
</Style>
Thank you !
You have nothing that will restrict the TextBlock.Width, so the text in it will never wrap, or be trimmed. To fix this problem, you just need to set some kind of Width restriction on it... you could try something like this:
<ControlTemplate>
<Border Padding="{TemplateBinding Padding}" VerticalAlignment="Center">
<TextBlock MaxWidth="250" TextTrimming="CharacterEllipsis">
...
Well, for WPF engine to understand that the trimming is needed it should see that the control cannot be put into the space available. If the control can be resized(AutoSize) it will just increase its dimensions without any trimming.
From MSDN:
Gets or sets the text trimming behavior to employ when content
overflows the content area.
And I can't see anything in your template that suggests that the space limit will be encountered.
So try to set width limit, either on Column, or on the TextBlock. Or restrict the resize in some other way.
<TextBlock Width="Auto" Height="Auto"
MaxWidth="100"
MinWidth="30"
TextTrimming="CharacterEllipsis">
I am pretty new to WPF and I am trying to build a quite simple application using MVVM light.
In my MainWindow.xaml (view) I have this :
<ListBox ItemsSource="{Binding InstalledVersions}"
ItemTemplate="{StaticResource VersionsDataTemplate}"
Style="{StaticResource VersionsStyle}"
ItemContainerStyle="{StaticResource VersionItemStyle}"/>
Where InstalledVersions is a list of InstalledVersionViewModel
In my MainWindowResources.xaml I have this (simplified) :
<DataTemplate x:Key="VersionsDataTemplate"
DataType="{x:Type viewmodels:InstalledVersionViewModel}">
<Grid>
<TextBlock Text="{Binding VersionNumber}" />
<TextBlock Text="{Binding FolderPath}" />
</Grid>
</DataTemplate>
<Style x:Key="VersionsStyle"
TargetType="{x:Type ListBox}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
<Style x:Key="VersionItemStyle"
TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="White" />
</Style>
I wish to have a different background depending on the "IsActive" property of my InstalledVersionViewModel.
I tried to add this (as well as several variations of it) to my VersionItemStyle but (as I suspected, mostly because I don't understand what I'm doing) it doesn't work :
<Style.Triggers>
<Trigger Property="{Binding Path=DataContext.IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type viewmodels:InstalledVersionViewModel}}}" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
Thanks !
Since IsActive is part of view model against each row you can achieve that with DataTrigger
<Style x:Key="VersionItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="White" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsActive}" Value="True">
<Setter Property="Background" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>