c# wpf, binding value of property depending on the bool value - c#

Sorry for my bad english. I want to bind a BorderBrush of ListBoxItem depending on the bool value of object.
I have a Directory class, that has IsForCopy and IsCutted bool props.
So, if IsForCopy is true, then BorderBrush = Red, if IsCutted is true, then BorderBrush = Blue. How can I do this?
ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="MouseDoubleClick" Handler="SecondListBoxItem_MouseDoubleClick"/>
<Setter Property="BorderBrush" Value="What do I should type there?"></Setter>
</Style>
</ListBox.ItemContainerStyle>

You need a class that implements IValueConverter. Then in the convert method you can specify how you want to map a bool to a brush any way you want. And every binding has a converter attribute which you can set to this class that implemented IValueConverter.

Related

How to set ProgressBarForeground in MahApps.Metro ProgressDialog?

I want to change the color of the progressbar inside of an ProgressDialog to HighlightColor.
With a CustomResourceDictionary i managed to change the button-style but not the color of the Progressbar
MetroDialogOptions.CustomResourceDictionary = new ResourceDictionary
{
Source = new Uri("pack://application:,,,/GUI;component/Styles/DialogDictionary.xaml")
};
DialogDictionary.xaml:
<Style x:Key="AccentedDialogSquareButton"
BasedOn="{StaticResource HighlightedSquareButtonStyle}"
TargetType="{x:Type ButtonBase}">
<Setter Property="Controls:ControlsHelper.ContentCharacterCasing" Value="Normal" />
</Style>
<Style TargetType="{x:Type Dialog:ProgressDialog}"
x:Key="NewProgressDialogStyle"
BasedOn="{StaticResource {x:Type Dialog:ProgressDialog}}">
<Setter Property="ProgressBarForeground" Value="Red" />
</Style>
<Style TargetType="{x:Type Dialog:ProgressDialog}"
BasedOn="{StaticResource NewProgressDialogStyle}" />
This is currently not possible.
The ProgressBarForeground property is set to a local value using the SetResourceReference method, so using a Setter in a Style has no effect - the local value always has a higher priority than the one coming from a Style.
You could try overriding the AccentColorBrush resource in your custom dictionary, but that won't work because the current theme code in Mahapps will scan all the merged resource dictionaries of the dialog and replace this resource with a special one that is defined as the "theme accent color".
See ThemeManager source code for details.
You have only two options:
change the accent color of your theme to the desired progress bar color (but then many controls will use this color for their appearance)
post a change request to the Mahapps team so that they provide a possibility to override the progress bar color in the ProgressDialog

Using a converter for more than one binding?

I would like to do something like this:
<Style TargetType="{x:Type Binding}">
<Setter Property="Converter" Value="{StaticResource converter1}"/>
</Style>
That doesn't work though. So how do I tell more than one binding which converter to use without writing it explicitly for every single one?
I'm sorry to say, but there are actually two reasons you cannot do this.
<Style TargetType="{x:Type Binding}">
<Setter Property="Converter" Value="{StaticResource converter1}"/>
</Style>
Firstly, you cannot create a style for System.Windows.Data.Binding because it does not meet the requirements for styling. The TargetType must derive from either FrameworkElement or FrameworkContentElement. Alas, Binding inherits from BindingBase, then MarkupExtension, then Object and so it cannot be styled.
Secondly, Setter.Property is of type DependencyProperty. Binding.Converter is not a dependency property, so it simply cannot have a value bound to it.
So, you will have to repeat the Converer={StaticResource converter1} within the braces of each XAML {Binding} markup extension.

Set a style color based on an object

I want to set the Background color of an object's style, to be the color of the Window Foreground. So.... how to get the color of one object and use it as the value in a style?
<Setter Property="Background" Value="????Window Foreground Color????" />
I've tried different binding combinations, but none of them have worked yet. In code-behind this value would be this.Foreground, but in XAML style?
Quickest way would be to give you parent Window a name and use that in binding. Something like this (if you named your window "Root"):
<Setter Property="Background" Value="{Binding ElementName=Root, Path=Foreground}" />

WPF - Trigger not firing

I'm having an issue when trying to do something which should be as easy as. I've attempted to use a Trigger based on a DependencyProperty or a DataTrigger - I can't get either to work.
XAML for the trigger is:
<Style x:Key="FileWatchButton" BasedOn="{StaticResource {x:Type Button}}" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="Main:Main.XmlFilesAvailableForLoading" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
And the associated code-behind is:
public static readonly DependencyProperty XmlFilesAvailableForLoadingProperty =
DependencyProperty.Register("XmlFilesAvailableForLoading", typeof(bool), typeof(Main));
public bool XmlFilesAvailableForLoading
{
get
{
try
{
return (bool)this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.DataBind,
(System.Windows.Threading.DispatcherOperationCallback)delegate { return GetValue(XmlFilesAvailableForLoadingProperty); },
XmlFilesAvailableForLoadingProperty);
}
catch (Exception)
{
return (bool)XmlFilesAvailableForLoadingProperty.DefaultMetadata.DefaultValue;
}
}
set
{
this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.DataBind,
(System.Threading.SendOrPostCallback)delegate{ SetValue(XmlFilesAvailableForLoadingProperty, value); }, value);
}
}
Basically the dp is being set correctly by the presenter (it's based on a FileSystemWatcher class looking for one or more files) but the Trigger is not being fired. Is this a threading issue?
Thanks.
It's not clear if the code is complete, but it looks like the Property path in your trigger may be wrong. Does the button being styled have a Main property? I am guessing not; it looks like you are trying to trigger on a property of a different element, called Main -- is that right?
In any case, the namespace prefix is not required. If the button has a property named Main, then you can address this directly; if it doesn't, then the prefix won't help you.
My guess is that you probably need a DataTrigger whose binding refers to the Main element:
<local:Main Name="MyMain" ... /> <!-- this has the XmlFilesAvailableForLoading property -->
<DataTrigger Binding="{Binding XmlFilesAvailableForLoading, ElementName=MyMain}"
Value=True>
<Setter Property="Background" Value="Red" />
</DataTrigger>
On an unrelated note, you should have any non-boilerplate implementation in your DP getter and setter. Remember that the binding and styling system will bypass the getter and setter and talk directly to the underlying storage. So I'd strongly advise changing these back to just plain GetValue and SetValue calls.

WPF Databinding and Styling based on Data in an item in an IList

I have a ListBox bound to a list of Items (for arguement, lets say its got a string and two dates Entered and Done).
I would like to make the background color of items in the ListBox have a gray color if the Done DateTime is != DateTime.MinValue.
Edit:
Should I make a converter? and convert DateTime to a Brush based on the value of the DateTime?
Is something like this my best option? or is there a simple Xaml snippet I could use?
[ValueConversion(typeof(DateTime), typeof(Brush))]
class MyConverter : IValueConverter
{
...
}
A ValueConverter would work. Another option would be to use a DataTrigger in the style of ListBoxItem. Maybe something like this:
<Style x:Name="MinDateTimeListBoxStyle" TargetType="ListBoxItem">
<Style.Triggers>
<Setter Property="Background" Value="Gray" />
<DataTrigger Binding="{Binding Path=Done}"
Value="{x:Static sys:DateTime.MinValue}">
<Setter Property="Background" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
This will set the background to Gray when the value of Done isn't DateTime.MinValue. I don't think there is a way to do a not equals comparison in a trigger, so it sets the background to Gray by default, and only changing it back to white if Done hasn't changed yet. It would probably be better to use the correct color for the background instead of white (maybe get the value of the parent's background?), but this should give you something to start with.
Update: To apply this style to the items of only certain ListBoxes, give the style a name and set the ItemContainerStyle as appropriate:
<ListBox x:Name="StyledListBox"
ItemContainerStyle="{StaticResource MinDateTimeListBoxStyle}" />
<ListBox x:Name="NormalListBox" />

Categories

Resources