Xceed Property Grid style name based on value - c#

I want to set background of "Name2" to gray because the value is "2".
How can I achieve this?
I tried using DataTrigger with a converter on "PropertyItem" but I had no luck.

You could define an EditorTemplate for the Name2 property:
<xctk:PropertyGrid ...>
<xctk:PropertyGrid.EditorDefinitions>
<xctk:EditorDefinition>
<xctk:EditorDefinition.PropertiesDefinitions>
<xctk:PropertyDefinition Name="Name2" />
</xctk:EditorDefinition.PropertiesDefinitions>
<xctk:EditorDefinition.EditorTemplate>
<DataTemplate>
<TextBlock Text="{Binding Value}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Value}" Value="2">
<Setter Property="Background" Value="Gray" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</xctk:EditorDefinition.EditorTemplate>
</xctk:EditorDefinition>
</xctk:PropertyGrid.EditorDefinitions>
</xctk:PropertyGrid>

Related

HOWTO make part of WPF TextBlock text bold without embbed another TextBlock and using property setter

I have below TexBlock and I should change dynamically its text property based on the value selected on a WPF Combobox.
<TextBlock Padding="5 10 0 0">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Text" Value="Select the items:" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MyWPFCombo, Path=Id}" Value="10">
<Setter Property="Text" Value="Select the old items:" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
My problem is that I need to set part of the text "Select the old items:" to bold, only the part "old items". In other scenarios I know that it can be done embbeding a textblock within it by in this case I need to set it using the setter. How to do it?
It's fiddly because you need part of the textblock to be bold and I don't think you can collapse an inline.
<StackPanel>
<TextBlock Padding="5 10 0 0">
<Run Text="Select the"/>
<Bold>
<Run>
<Run.Style>
<Style TargetType="Run">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MyWPFCombo, Path=SelectedValue}" Value="10">
<Setter Property="Text" Value="old items:" />
</DataTrigger>
</Style.Triggers>
</Style>
</Run.Style>
</Run>
</Bold>
<Run>
<Run.Style>
<Style TargetType="Run">
<Setter Property="Text" Value="items:" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MyWPFCombo, Path=SelectedValue}" Value="10">
<Setter Property="Text" Value="" />
</DataTrigger>
</Style.Triggers>
</Style>
</Run.Style>
</Run>
</TextBlock>
<ComboBox x:Name="MyWPFCombo"
SelectedValuePath="Id"
DisplayMemberPath="Description"
ItemsSource="{Binding Items}"/>
</StackPanel>

WPF binding not applied - why does it happen

I wanted to update a stringformat of my binding via a datatrigger. So I thought of just doing this:
<TextBlock Text="{Binding Foo.Name}" Margin="3">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{Binding Path=., StringFormat='Start {0}'}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Foo.IsEnabled}" Value="True">
<Setter Property="Text" Value="{Binding Path=., StringFormat='Stop {0}'}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
now this just shows the value of Foo.Name and not with the string format applied('start'/'stop' string).
I've modified the code, to get it working. This is the working code:
<TextBlock Margin="3">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{Binding Foo.Name, StringFormat='Start {0}'}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Foo.IsEnabled}" Value="True">
<Setter Property="Text" Value="{Binding Foo.Name, StringFormat='Stop {0}'}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Now i'm looking for the reason why the first piece of code doesn't work and why the second piece of code works.
I've seen similar behavior in DataTemplates where I could not set or alter a property value via a Setter in a DataTrigger because the property was already set directly via the property on the object itself. Only when I removed the property from the object itself and set it as a style it worked.
Or is this just a limitation in WPF?
I wouldn't call it a limitation, it's documented. Dependency properties have a value precedence. https://msdn.microsoft.com/en-us/library/ms743230(v=vs.110).aspx

DataTrigger for IconTemplate in RadWindow

I have a WPF application and I use Telerik.
I'm trying to set the Icon Template so that it has a default value and only on a certain condition will it bind the image source:
<telerik:RadWindow.Resources>
<Style x:Key="CustomIconStyle" TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsConditionMet, ElementName=MyWindow, UpdateSourceTrigger=PropertyChanged}" Value="True">
<Setter Property="Source" Value="{Binding Path=IconImageSource, ElementName=MyWindow, UpdateSourceTrigger=PropertyChanged}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadWindow.Resources>
<telerik:RadWindow.IconTemplate>
<DataTemplate>
<Image Style="{StaticResource CustomIconStyle}" Source="/MyAssembly;Component/Resources/myIcon.ico" Height="16" Margin="0,0,5,0"/>
</DataTemplate>
</telerik:RadWindow.IconTemplate>
For some reason it always show the default icon.
I would also like to mention that I did implement the property changed - and I copied the same style just to a control inside the window and not in the template and it worked - so the problem isn't with the property changed
Any ideas?
You can use Triggers like that :
<telerik:RadWindow.Resources>
<Style TargetType="Image" x:Key="Style1">
<Setter Property="Source" Value="default.ico"/>
<Style.Triggers>
<DataTrigger Binding="{Binding MyCondition}" Value="true">
<Setter Property="Source" Value="custom.ico"/>
</DataTrigger>
</Style.Triggers>
</Style>
</telerik:RadWindow.Resources>
<telerik:RadWindow.IconTemplate>
<DataTemplate>
<Image Style="{StaticResource Style1}" Height="16" Margin="0,0,5,0"/>
</DataTemplate>
</telerik:RadWindow.IconTemplate>
So the problem was that once the RadWindow was loaded it didn't change the Icon.
The solution:
<telerik:RadWindow.IconTemplate>
<DataTemplate>
<Image Height="16" Margin="0,0,5,0">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/MyAssembly;Component/Resources/myIcon.ico" />
<Style.Triggers>
<DataTrigger Value="True" Binding="{Binding Path=IsConditionMet, ElementName=MyWindow}">
<Setter Property="Source" Value="{Binding Path=IconImageSource, ElementName=MyWindow}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</DataTemplate>
</telerik:RadWindow.IconTemplate>
But the trick is to give the correct value of IsConditionMet in the windows constructor before the load.
Thanks for the help everyone.

How to Bind an another Control on the Setter Value Property by using a Trigger?

i've a little Problem with the Databinding in WPF an hope you can help me.
I want to bind the SelectedDate Parameter of a DatePicker on a TextBlock, but only when a CheckBox is checked. The CheckBox and the TextBlock are in a DataView, the DatePicker is outside.
In the Moment i try to use it with a Trigger an set the Binding in the Value-Property in the Setter Part.
<TextBlock Text="">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked}" Value="True">
<Setter Property="Text" Value="{Binding ElementName=StandartPitBis, Path=SelectedDate, StringFormat='dd.MM.yyyy'}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
But this will not works. Has anywone a Tipp what i can do?
Here is the Code-Parts there i'm using:
Inside the GridView
The CheckBox
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Content="" x:Name="check_Anlage" IsChecked="{Binding Path=IsChecked}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
The TextBlock
<TextBlock Text="">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked}" Value="True">
<Setter Property="Text" Value="{Binding ElementName=StandartPitBis, Path=SelectedDate, StringFormat='dd.MM.yyyy'}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Outside the GridView
The DatePicker
<DatePicker Grid.Column="1" Margin="0,5,0,5" SelectedDate="{x:Static sys:DateTime.Now}" x:Name="StandartPitVon" />
What i want to make is, that the SelectedDate from the DatePicker is shown in the TextBlock, but only when the CheckBox is Checked.
Thanks a lot
So. I've found the Problem. The Problem is, when a Property is set in the Object self, then it can't be overridet. When you need a Default-Value and a Trigger, then you must define the Default-Value in the Style too.
Example:
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{x:Null}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked}" Value="True">
<Setter Property="Text" Value="{Binding ElementName=StandartPitVon, Path=SelectedDate, StringFormat='dd.MM.yyyy'}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>

DataTemplate Based on Value of Bound Property in ItemsSource of TabControl

Ok. So I have a TabControl object in my xaml that has an ItemsSource value of ItemsSource={Binding OpenTabs} where OpenTabs is an ObservableCollection of type ClosableTab (public ObservableCollection<ClosableTab> OpenTabs { get; set; }) which extends TabItem. I found ClosableTab from here and then have adapted it's view for my own needs.
Primarily I have added a property (and sorry for the confusion in names here) isProperty. This is for a real estate program. Then in my xaml I have the following lines:
<DataTemplate x:Key="PropertyTemplate">
<Grid>
<TextBlock Text="{Binding address}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="TennantTemplate">
<Grid>
<TextBlock Text="{Binding name}"/>
</Grid>
</DataTemplate>
//... That's in <Windows.Resources>
<TabControl ItemsSource="{Binding OpenTabs}" Grid.Column="1" x:Name="Tabs">
<TabControl.Resources>
<DataTemplate x:Key="DefaultTab">
<ContentControl>
<ContentControl.Triggers>
<DataTrigger Binding="{Binding isProperty}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource PropertyTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding isProperty}" Value="False">
<Setter Property="ContentTemplate" Value="{StaticResource TennantTemplate}" />
</DataTrigger>
</ContentControl.Triggers>
</ContentControl>
</DataTemplate>
</TabControl.Resources>
</TabControl>
I've done some research and found that this is what I need to do if I want to have a certain DataTemplate dependant on the property in ClosableTab called isProperty.
It's not giving me what I want. Can someone please explain to me what I'm doing wrong here? And tell me what I should do? And/or possibly give me an alternative method? I can't think of what I need to change to get the functionality that I need. Thanks in advance.
You need to set DataType on DataTemplate to get it applied automatically to underlying data objects in case you are defining DataTemplate under Resources section.
<DataTemplate DataType="local:ClosableTab">
<ContentControl>
<ContentControl.Triggers>
<DataTrigger Binding="{Binding isProperty}" Value="True">
<Setter Property="ContentTemplate"
Value="{StaticResource PropertyTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding isProperty}" Value="False">
<Setter Property="ContentTemplate"
Value="{StaticResource TennantTemplate}" />
</DataTrigger>
</ContentControl.Triggers>
</ContentControl>
</DataTemplate>
Make sure to declare local namespace at root level to the one where ClosableTab is declared.
OR
Instead of adding DataTemplate in resources, set it explicitly as ItemTemplate of TabControl.
<TabControl>
<TabControl.ItemTemplate>
<DataTemplate x:Key="DefaultTab">
.....
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
UPDATE
Ideal case would be to have single DataTemplate and apply dataTrigger on TextBlock instead.
<TabControl ItemsSource="{Binding OpenTabs}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text" Value="{Binding address}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding isProperty}"
Value="False">
<Setter Property="Text" Value="{Binding name}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>

Categories