WPF Multibuilding 2 Values to the same Property - c#

I have a table, and when the user would like to mark a row. he can click on button and mark it.
so I wrote a converter for the property, that if its true it return color(yellow)
and if false it return white,
however it Deletes the default style when user select a row in the table.
I was thinking of using Multibuilding once for mark, and one for selected.
however I am not understand what the syntax should be in WPF.
attaching the code I wrote,
will appreciate a code examples.
WPF:
<Style TargetType="syncfusion:GridCell" x:Key="ComCell">
<Setter Property="Foreground" Value="{Binding COMPort , Converter={StaticResource CVconverters } }" />
<Setter Property="Background" Value="{Binding isBookMarked, Converter={StaticResource BookMarkConverter}}"></Setter>
</Style>
C#:
public class BookMarkConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string valStr = value.ToString();
if (valStr == "True")
{
return Brushes.Yellow;
}
else
{
}
return Brushes.White;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

Instead of returning Brushes.White from the converter, you could return Binding.DoNothing from the converter if you simply don't want to change the background.
You could also base your Style on the default one:
<Style TargetType="syncfusion:GridCell" x:Key="ComCell"
BasedOn="{StaticResource {x:Type syncfusion:GridCell}}">

Related

Is it possible to bind a property to itself through a converter in WPF?

I need to change value of a property on a trigger, and I need to do it according to the existing value with some parameter. So, I've tried to use xaml like this:
<Style.Triggers>
<Trigger ...>
<Setter Property="BorderBrush"
Value="{Binding Path=BorderBrush,
RelativeSource={RelativeSource Self},
Converter={StaticResource MyConverter},
ConverterParameter=ParamValue}" />
</Trigger>
</Style.Triggers>
And converter is simple:
[ValueConversion(typeof(SolidColorBrush), typeof(SolidColorBrush))]
public class MyConverter : IValueConverter
{
public object Convert(object existingValue, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//change the brush
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
But with such code existingValue parameter in MyConverter.Convert() is null.
So, is there a way to apply converter to a property using its own value? I can't pass it as ConverterParameter because that is used for another data needed by the converter.

Set specific style on user control based on custom DP [duplicate]

I have a requirement to change a button's style based on a value in the data. It looks like a StyleSelector would work perfectly but there doesn't seem to be a way to set one for a button.
Is there a way to set a button style dynamically from data? Maybe even a pure XAML approach?
A more general way to accomplish the same thing:
SomeView.xaml
<UserControl>
<UserControl.Resources>
<converters:BooleanToStyleConverter x:Key="MyButtonStyleConverter"
TrueStyle="{StaticResource AmazingButtonStyle}"
FalseStyle="{StaticResource BoringButtonStyle}"/>
</UserControl.Resources>
<Grid>
<Button Style={Binding IsAmazingButton, Converter={StaticResource MyButtonStyleConverter}}/>
</Grid>
</UserControl>
BooleanToStyleConverter.cs
public class BooleanToStyleConverter : IValueConverter
{
public Style TrueStyle { get; set; }
public Style FalseStyle { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is bool && (bool) value)
{
return TrueStyle;
}
return FalseStyle;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
This converter works in any view with any kind of control using whatever style you choose as long as you are binding to a Boolean property in your ViewModel to control the style switching. Easy to adapt it to other binding requirements though. This works in a DataTemplate as well.
You could place your Button Styles in a Resource Dictionary and bind the Style for the Button and use a Converter
ButtonStyles.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ButtonStyle1" TargetType="Button">
<Setter Property="Background" Value="Green"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<Style x:Key="ButtonStyle2" TargetType="Button">
<Setter Property="Background" Value="Red"/>
<Setter Property="FontSize" Value="14"/>
</Style>
</ResourceDictionary>
Then for the Button that has this requirement you bind Style to the property of interest
<Button ...
Style="{Binding Path=MyDataProperty,
Converter={StaticResource ButtonStyleConverter}}"/>
And in the Converter you load the ButtonStyles Resource Dictionary and return the desired Style based on the value
public class ButtonStyleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Uri resourceLocater = new Uri("/YourNameSpace;component/ButtonStyles.xaml", System.UriKind.Relative);
ResourceDictionary resourceDictionary = (ResourceDictionary)Application.LoadComponent(resourceLocater);
if (value.ToString() == "Some Value")
{
return resourceDictionary["ButtonStyle1"] as Style;
}
return resourceDictionary["ButtonStyle2"] as Style;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

Is there a way to bind the Enabled property of a button to a checkbox's Checked property?

I want to bind IsEnabled of Button in WPF as follows:
WPF Code:
<Button Content="TestButton" IsEnabled="{Binding ??}" />
C# code:
private MyObjectClass _Checked;
public MyObjectClass Checked
{
get { return _Checked; }
set
{
_Checked = value;
RaisePropertyChanged("Checked");
}
}
In WPF code above, I want the button to be enabled only when Checked object is not null. I know one way is to have a bool property in C# code which tells me whether the Checked object is null or not, and then bind it to IsEnabled property. I want to know if there is a way I can bind IsEnabled to Checked object directly?
Use DataTrigger and check for {x:Null} value of binding:
<Button Content="TestButton">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding Checked}" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Also, you can use IValueConverter which will return false if value is null otherwise true.
public class ObjectToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
bool returnValue = true;
if (value == DependencyProperty.UnsetValue || value == null)
{
returnValue = false;
}
return returnValue;
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
return Binding.DoNothing;
}
}
and bind in XAML:
<Button Content="TestButton"
IsEnabled="{Binding Checked,
Converter={StaticResource ObjectToBoolConverter}}" />
Ofcourse you need to declare instance of converter in your XAML for this.
You can use a converter to convert an object into a bool. Look into IValueConverter.
public class IsNotNullToBoolConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value != null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException("Two-way binding not supported by IsNotNullToBoolConverter");
}
}
And your xaml would look like this:
<Window.Resources>
<local:IsNotNullToBoolConverter x:Key="IsNotNull" />
</Window.Resources>
...
<Button IsEnabled="{Binding Converter={StaticResource IsNotNull}}" />
I know this is an old issue but you can do this without an extra code. Just add the "TargetNullValue=false" to the binding.
IsEnabled="{Binding SomeProperty, TargetNullValue=false}"

WPF - Highlighting rows in listview with binded XML

First of all I apologise for my bad english.
I have xml binded to a listview, where each row stands for one person. I want row's background color blue or pink depending on sex element in xml. I've created style with triggers, but they seems to check only first xml node and all rows are colored same as 1st row.
Xml element sex is 0 for male, 1 for female.
One DataTrigger (second is similar):
<DataTrigger Binding="{Binding Source={StaticResource Data}, XPath=People/Person/Sex}" Value="0">
<Setter Property="Background" Value="{StaticResource MaleBrush}" />
</DataTrigger>
This is xml and style binding to listview (data is XmlDataProvider):
<ListView ... ItemsSource="{Binding Source={StaticResource Data}, XPath=People/Person}" ItemContainerStyle="{StaticResource SexStyle}">
And this is style header:
<Style x:Key="SexStyle" TargetType="{x:Type ListViewItem}">
Thanks for help!
You should use a ValueConverter for this.
You bind the background of the datatemplate to the gender.
Then you create a value converter class like this:
public sealed class GenderToBackgroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string) {
if (Convert.ToString(value) == "m") {
return Colors.Blue;
} else {
return Colors.Pink;
}
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
This value converter you then add to your resources like this:
<local:GenderToBackgroundConverter x:Key="GenderToBackgroundConverter" />
And in your datatemplate:
<Stackpanel Background={Binding Sex, Converter={StaticResource GenderToBackgroundConverter}}">
</Stackpanel>

WPF Calling method from a DataTrigger

Is it possible to use a wild card or call a method to work out if a DataTrigger should be applied?
I currently have my DataList bound to an IEnumerable that contains file names and I want the file names to be greyed out if there files extension starts with "old"
My non-working dream xaml markup looks something like this:
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding}" Value="*.old*">
<Setter TargetName="FileName" Property="Foreground" Value="Gray"/>
</DataTrigger>
</DataTemplate.Triggers>
The only workable solution I've been able to come up with is to insert a new view model property that contains this logic, but I would like to avoid changing the view model if possible.
The answer to both questions is yes....in a roundabout way
If you use a Binding Converter you can pass a parameter to it and have it return a boolean, that would be an effective way to do what you describe.
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=., Converter={StaticResource myFileExtensionConverter}, ConverterParameter=old}" Value="True">
<Setter TargetName="FileName" Property="Foreground" Value="Gray"/>
</DataTrigger>
</DataTemplate.Triggers>
where the converter would look something like this
public class MyFileExtensionConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
Boolean returnValue = false;
String fileExtension = parameter as String;
String fileName = value as String;
if (String.IsNullOrEmpty(fileName)) { }
else if (String.IsNullOrEmpty(fileExtension)) { }
else if (String.Compare(Path.GetExtension(fileName), fileExtension, StringComparison.OrdinalIgnoreCase) == 0) {
returnValue = true;
}
return returnValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
return value;
}
}
basically when the file extension matches you get a "true" which will fire the trigger.

Categories

Resources