I built a WPF application and manage to get the validation working thanks to posts on stackoverflow.The only probblem i'm having is that it's overriding the theme i'm using.
example the theme makes the textboxes look like a round rectangle but after setting the binding it look like the default textboxes. here is my code :
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="false" />
<Style.Triggers>
<!-- Require the controls to be valid in order to press OK -->
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=txtEmail, Path=(Validation.HasError)}" Value="false" />
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="true" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
code behind is:
//Form loaded event code
txtEmail.GetBindingExpression(TextBox.TextProperty).UpdateSource();
I've tried to look into the theme file but i was quickly lost.i thought i could use that file like a web css file.Now i've disabled the data binding because of that.Is there any work around for this? thanks for reading this
Not sure if that's the root problem, but try adding BasedOn="{StaticResource {x:Type Button}}" to style element.
Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}">
...
Related
I meet a problem with Fluent Ribbon. I didn't change anything in XAML, but all Headers of my buttons disapeared. I don't know if it is a bug, or simply a shortcut to change appearance and Hide/Show headers.
Here is how looks the ribbon :
And how it looks like from now :
I tried to restart solution but nothing changed, same if I restart VisualStudio. But if I load a backup of solution last week all is working fine, that's why I think there is maybe a shortcut to make them appear/disappear?
Edit :
After additional tests I can add :
Issue is present in both Debug and Release mode
Problem is on all the solution, in all windows using Ribbon, not only that one
If the code is OK, close the project and clear the cache. After that do not forget to delete the folders "bin" and "debug" and "release". Open the project, do a rebuild. Hope to help.
I finally decided to restart from a backup, and modify again the code file after file to finally find the issue (apologies to whom I said that I didn't modify xaml, didn't remember about that one, and didn't notice inmediately that this caused a problem).
In my App.xaml file I use the following style :
<Style TargetType="ToolTip">
<Style.Triggers>
<Trigger Property="Content"
Value="{x:Static sys:String.Empty}">
<Setter Property="Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="Content"
Value="{x:Null}">
<Setter Property="Visibility"
Value="Collapsed" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="Content"
Value="{x:Static sys:String.Empty}">
<Setter Property="Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="Content"
Value="{x:Null}">
<Setter Property="Visibility"
Value="Collapsed" />
</Trigger>
</Style.Triggers>
I had to remove all the block and all is working again.
But then I don't understand why Ribbon headers are influented by the style? Well I guess the headers are in textboxes, but they are not empty?
All around my project I'm facing similar problem, which is "Enter" key, creating new line in cell, instead of move to next line.
My current telerik version is 2018.1.122.45, and default, expected behavior is to leave cell, after pressing "Enter" key (according to telerik documentation, and helpdesk).
However, in my case it always makes new line within cell being edited.
I'm using Visual Studio 2013 theme, my implementation of RadGridView is correct, I've pasted my RadGridView, to project, I got from telerik support, and there, Enter was working as expected. Also, they've pasted my RadGridView implementation to their project and it also worked correctly.
Have anyone faced similar problem? I'm looking for solution, since I can't track source of this issue (even with teleriks help).
I've found a solution to this problem, and other Styles problems. Implementing style in the way demonstrated in telerik documentation (f.e. https://docs.telerik.com/devtools/wpf/controls/radgridview/styles-and-templates/styling-a-row) has some issues not mentioned in documentation.
<Style TargetType="telerik:GridViewRow">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White"/>
</Style>
This is one of the simpliest examples of implementing style. In my case it was:
<Style TargetType="telerik:GridViewCell"
x:Key="IloscNormalStyle"
BasedOn="{StaticResource GridViewCellStyle}">
<Setter Property="Background"
Value="#c3d8c7" />
<Setter Property="Foreground"
Value="Black" />
</Style>
And it works just fine. The biggest issue is that it completly ignores implemented Theme for project and all it's behaviours, which are, for example, selection behavior, enter key press, borders, etc. In order to tell style to not ignore implemented theme, I needed to insert this code to my styles:
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=telerik:GridViewRow}}"
Value="True">
<Setter Property="Background"
Value="{Binding Background}" />
</DataTrigger>
</Style.Triggers>
Which finally made my style works with desired behavior. Full style code:
<Style TargetType="telerik:GridViewCell"
x:Key="IloscNormalStyle"
BasedOn="{StaticResource GridViewCellStyle}">
<Setter Property="Background"
Value="#c3d8c7" />
<Setter Property="Foreground"
Value="Black" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=telerik:GridViewRow}}"
Value="True">
<Setter Property="Background"
Value="{Binding Background}" />
</DataTrigger>
</Style.Triggers>
</Style>
I think it is a major issue for telerik (or maybe even WPF), but this couple lines of code resolves most of problems with custom cell/row styling.
I want to give mij text on my button a customized color in the MainWindow.xaml.cs
Normally you give the color in the cs file by this way to the command:
ToggleButton.Foreground = Brushes.Green;
But I want to give the hexnumber
I've already tried something like this :
SolidColorBrush Owncolor = (SolidColorBrush)(new BrushConverter().ConvertFrom("#FF5D0000"));
ToggleButton.Foreground = Brushes.Owncolor;
Instead of doing it in code behind (unless you have a very specific reason to do that), you can work on your xaml
<ToggleButton Foreground = "#FF5D0000"/>
if you are doing it based on some condition, also please take a look at this. It's always a better practice to handle graphical stuff in your xaml as much as you can
for instance you can do
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Foreground" Value="Green"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
Usually in WPF you tend to use styles defined in XAML to change how controls looks. However, using the BrushConverter works if you absolutely have to use the hexadecimal syntax in codebehind. I'd consider building a new SolidColorBrush with Color.FromArgb easier, but that also works.
As for how to use styles and XAML properly, you should probably read some tutorials or books. WPF is quite a different beast than Windows Forms or a lot of older UI frameworks, so there's some re-learning required.
The simplest way of achieving what you want (a different text colour when the button is pressed) would be the following style:
<Style TargetType="ToggleButton">
<Setter Property="Foreground" Value="#FF5D0000"/>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
When placed in the Resources of your Window it would apply to all ToggleButtons in that window.
I want to define triggers as resources to use them later in my controls.
Like this:
<Window.Resources>
<DataTrigger x:Key="Trigger1" Binding="{Binding ViewModelProperty1}" Value="Val1">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
<DataTrigger x:Key="Trigger2" Binding="{Binding ViewModelProperty2}" Value="Val2">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
...
</Window.Resources>
However, when I try to run the code, the compiler complains that IsEnabled is not a valid member. I think this is because it cannot know if the control in question will even have the property "IsEnabled". Like with styles, I think I need to somehow specifiy the TargetType (which would be, in my case, FrameworkElement). But how?
NOTE:
Please do not suggest to use styles instead of triggers as resources. Since a control can only have ONE style, but I need to give SEVERAL triggers to one control, styles are no option here:
In my actual code I have a Button that should have trigger 1, 2 and 4 and a TextBox that should have trigger 1 and 3 and a Label that should have trigger 2, 3 and 4... I think you get it.
You can do it like this (note how I prepend IsEnabled with FrameworkElement and also how I reference those resources from style triggers):
<Window.Resources>
<DataTrigger x:Key="Trigger1"
Binding="{Binding ViewModelProperty1}"
Value="Val1">
<Setter Property="FrameworkElement.IsEnabled"
Value="False" />
</DataTrigger>
<DataTrigger x:Key="Trigger2"
Binding="{Binding ViewModelProperty2}"
Value="Val2">
<Setter Property="FrameworkElement.IsEnabled"
Value="False" />
</DataTrigger>
</Window.Resources>
<Button>
<Button.Style>
<Style>
<Style.Triggers>
<StaticResource ResourceKey="Trigger1" />
<StaticResource ResourceKey="Trigger2" />
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I have the following style defined in my XAML to enable buttons only when something in the DataContext has changed (IsDirty = true) :
<!-- Style for Buttons to enable based on IsDirty value -->
<Style x:Key="EnableWhenDirtyButtonStyle" TargetType="{x:Type Button}"
BasedOn="{StaticResource ButtonStyle}">
<Setter Property="IsEnabled" Value="False" />
<Style.Triggers>
<!-- Enable button when something has changed -->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}, Path=DataContext.IsDirty}" Value="True">
<Setter Property="Button.IsEnabled" Value="true" />
</DataTrigger>
</Style.Triggers>
</Style>
This works as long as there is only one DataContext within the UserControl. I now have the situation where I have 3 different DataViews so I have 3 different IsDirty values (i.e., CustomerTableIsDirty, OrderTableIsDirty, OrderDetailTableIsDirty). In this case I can create three new *DisableWhenDirtyButtonStyle in the UserControl like:
<Style x:Key="CustomerTableEnableWhenDirtyButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource ButtonStyle}">
<Setter Property="Button.IsEnabled" Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=CustomerTableIsDirty}" Value="true">
<Setter Property="Button.IsEnabled" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
Is there a way to create a DataTrigger such that the binding value can be passed into the style as a parameter?
Alternatively, is there a way to add conditions to a MultiDataTrigger when inheriting a style via 'BasedOn' which would already have a MultiDataTrigger defined. For instance:
<Style x:Key="CustomerTableEnableWhenDirtyButtonStyle"
TargetType="{x:Type Button}"
BasedOn="{StaticResource EnableWhenDirtyButtonStyle}">
<!-- Add the following to existing MultiDataTrigger in EnableWhenDirtyButtonStyle -->
<Condition Binding="{Binding Path=CustomerTableIsDirty}" Value="true" />
</Style>
I CANNOT use MultiBinding as this style is part of a base project which gets used by multiple other projects (as a DLL). The users of this DLL would not be able to update the style to include the necessary Binding Path.
Instead of using 3 different names, just use a single name IsDirty.