Multivalue Bound Textblock DataTrigger not firing - c#

So I'm trying to Bind a TextBlock to multiple values on my Viewmodel (Mix of Enums and Strings). I have a DataTrigger that is supposed to fire when the text is null when returned by the Converter. But it doesn't! At first, I thought my Style didn't take hold (hence changed the Background on the Style to show it did). Anyway here is the code
XAML
<TextBlock x:Name="MyTextBlock" Grid.Column="2" Grid.ColumnSpan="3" VerticalAlignment="Center" DataContext="{StaticResource ViewModelLocator}"
Margin="{Binding RelativeSource={RelativeSource Self}, Path=(params:General.BoldPadding), Mode=OneWay}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource GeneralMultiStringDisplayConverter}">
<Binding Path="RatesViewModel.Instrument.Currency" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="RatesViewModel.Instrument.Underlying" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="RatesViewModel.Instrument.ProductType" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</TextBlock.Text>
<TextBlock.Resources>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource HeaderTextStyle}">
<Setter Property="Background" Value="Blue"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MyTextBlock, Path=Text}" Value="{x:Null}"> <!--THIS SHOULD FIRE-->
<Setter Property="Text" Value="ThisShouldFireOnStart"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Resources>
</TextBlock>
The Converter is as follows:
class GeneralMultiStringDisplayConverter:IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var AS = DependencyProperty.UnsetValue;
if (values[0] != AS )
{
int count = values.Count();
string result = string.Empty;
for (int i = 0; i < count - 1; ++i)
{
try
{
var A = Enum.GetName((values[i].GetType()), values[i]);
result = String.Format("{0}{1}.", result, A);
}
catch (Exception ex)
{
result = String.Format("{0}{1}.", result, values[i]);
}
}
result = String.Format("{0}{1}", result, values[count - 1]);
return result;
}
return null;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return null;
//TODO:
}
}
Debugging Steps that I have taken
`<Setter Property="Text" Value="ABC"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MyTextBlock, Path=Text}" Value="ABC">
<Setter Property="Text" Value="ThisShouldFireOnStart"/>
</DataTrigger>
</Style.Triggers>
`
Added a converter to the Styles DataTrigger Binding. It always gets "" as a parameter and not null for some reason. Setting the trigger Value to "" does not work.
Added a default Text property in the Style and tried changing the Value based off of that. (See example above)
I would appreciate some help in getting this to work
Thanks!

You can not override these local bindings with a DataTrigger in a Style.
See Why doesn’t my WPF Trigger work?
If you just need to show a string if your bindings are null use TargetNullValue="MyNullValueString"
Perhaps you need a if(value[0] != null) condition in your converter to identify unset properties. Since i do not have any detail of your RatesViewModel i can not say for sure.
<MultiBinding Converter="{StaticResource GeneralMultiStringDisplayConverter}" TargetNullValue="ThisIsNull">
<Binding Path="RatesViewModel.Instrument.Currency" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="RatesViewModel.Instrument.Underlying" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="RatesViewModel.Instrument.ProductType" NotifyOnSourceUpdated="True" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>

Related

change checkbox state in DataGridTemplateColumn after row is selected in datagrid using xaml

I am creating a wpf app and struggling with this problem for sometime now.
I have a datagrid with DataGridTemplateColumn, which contains a checkbox and textblock.
<DataGrid
Name="ChargeDataGrid"
Grid.Row="1"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox x:Name="CheckBox1"/>
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox />
<TextBlock Text="Title" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<system:String>123</system:String>
<system:String>124</system:String>
<system:String>125</system:String>
<system:String>126</system:String>
<system:String>127</system:String>
</DataGrid>
What i need to achieve is when row is clicked checkbox in this row must be in checked state too.
I tried to use style triggers:
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="CheckBox1.IsChecked" Value="True" />
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
but it didn't seem possible to change checkbox state like this. I know how to do it in code-behind or mvvm style, but in this case i am wondering is it possible to do using xaml only?
Any help would be appreciated.
I am afraid but with plain standard XAML you can't do it.
As I see you have two options:
You can use some extension libraries which will expand functionality of bindings. Some functionality can be found in mvvm frameworks like MugenMvvmToolkit
Second option is to use some converter for this purpose.
My solution for the second variant is a kind of hack and to my mind more elegant way would be with code behind. Converter:
public class MultiValueConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length != 3) throw new ArgumentException("Should be 3 params");
if (!(values[2] is FrameworkElement element)) return values[1];
if (!(bool)values[0])
{
element.Tag = "Value need to be changed.";
return values[1];
}
if (element.Tag.Equals("Value changed.")) return values[1];
var res = !(bool)(values[1] ?? true);
element.Tag = "Value changed.";
return res;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Converter inversing bool variable and saves previous state in Tag property of control. This is still not code behind and pretty reusable solution. You can use such converter in any other view where you need such behaviour
In XAML I've changed only checkbox control definition:
<CheckBox x:Name="RowCheckBox" IsHitTestVisible="False">
<CheckBox.IsChecked>
<MultiBinding Converter="{StaticResource MultiValueConverter}" Mode="OneWay">
<Binding Path="IsSelected" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}" />
<Binding Path="IsChecked" RelativeSource="{RelativeSource Self}" />
<Binding Mode="OneWay" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
I think it can bed done rather simple like this:
<CheckBox x:Name="CheckBox1" IsChecked="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=IsSelected}"/>
EDIT:
If the desired result is to only change the IsChecked state when (re)selecting the row it can be done with a attached property on a DependencyObject (for instance the containing window) like this:
1) Define the checkbox as this:
<CheckBox x:Name="CheckBox1" IsEnabled="true" local:MainWindow.CheckboxChecked="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=IsSelected,Mode=OneWay}">
2) Define the attached property as this:
public static bool GetCheckboxChecked(DependencyObject obj)
{
return (bool)obj.GetValue(CheckboxCheckedProperty);
}
public static void SetCheckboxChecked(DependencyObject obj, bool value)
{
obj.SetValue(CheckboxCheckedProperty, value);
}
public static readonly DependencyProperty CheckboxCheckedProperty =
DependencyProperty.RegisterAttached("CheckboxChecked", typeof(bool), typeof(MainWindow), new PropertyMetadata(false, CheckboxChecked_Changed));
private static void CheckboxChecked_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CheckBox chk = d as CheckBox;
if (chk != null && chk.Tag == null)
{
bool chkValue = chk.IsChecked.GetValueOrDefault();
bool oldValue = (bool)e.OldValue;
bool newValue = (bool)e.NewValue;
chk.Tag = true; // Just to prevent an infinite loop
chk.IsChecked = !chkValue && !newValue || chkValue && !oldValue && newValue ? false : true;
chk.Tag = null;
}
}

Aligning my Popup to bottom of Window

im trying to align my Popup to the bottom center of my Window, how ever i'm getting this error:
Additional information: Specified cast is not valid.
This is being caused by my converter double windowWidth = (double)values[0];, how ever the ActualWidth should bee a double! Not too sure on what is going wrong here.
I'm currently showing the data in a MessageBox just to test it at the moment and make sure the values look correct.
Converter
namespace Test_Project.Converters
{
public class NotificationOffsets : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double windowWidth = (double)values[0];
double notificationWidth = (double)values[1];
MessageBox.Show("Notification Width: " + notificationWidth.ToString() + " Window Width: " + windowWidth.ToString());
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
XAML - Converter Binding
<Style TargetType="Popup" x:Key="PopupNotification">
<Setter Property="IsOpen" Value="True" />
<Setter Property="HorizontalOffset">
<Setter.Value>
<MultiBinding Converter="{StaticResource NotificationOffsets}">
<Binding RelativeSource="{RelativeSource Self}" Path="PlacementTarget.ActualWidth" />
<Binding RelativeSource="{RelativeSource Self}" Path="ActualWidth" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
Edit:
Breakpoint Data:
Edit 2:
I have now set my PlacementTarget within my Style:
<Setter Property="PlacementTarget" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" />
Still getting the same error!
You have to return a double on your converter, you are returning a boolean, which cause the invalid cast.
EDIT: You are having Binding problems, you have to set the "PlacementTarget" of your popup in order the get the Width property.
EDIT 2: try this:
<Window x:Class="WpfApplication7.MainWindow"
Name="myWindow"
............
<Setter Property="PlacementTarget" Value="{Binding ElementName=myWindow}"/>

Positioning of Axis Label in a DateTimeAxis

At the moment I have a date time axis where the date is in-line with the points, is there anyway to get this date to appear in the center such as on a bar chart.
<Style x:Key="DateTimeAxisLabelStyle2" TargetType="chartingToolkit:DateTimeAxisLabel">
<Setter Property="DaysIntervalStringFormat" Value="{}{0:dd-MMM}" />
<Setter Property="HoursIntervalStringFormat" Value="{}{0:hh:mm tt}" />
<!--<Setter Property="RenderTransformOrigin" Value="1,0.5" />
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="-45" />
</Setter.Value>
</Setter>-->
<!--<Setter Property="Margin" Value="30,0,-10,0" />-->
</Style>
<chartingToolkit:DateTimeAxis IntervalType="Days"
Interval="1"
Minimum="{Binding StartDate}"
Maximum="{Binding EndDate}"
Orientation="X"
VerticalContentAlignment="Center"
Title="Day"
AxisLabelStyle="{StaticResource DateTimeAxisLabelStyle2}" />
Any help would be greatly appreciated.
Here's what i got:
XAML:
<Window.Resources>
<Style x:Key="DateTimeAxisLabelStyle1" TargetType="{x:Type chartingToolkit:DateTimeAxisLabel}">
<Setter Property="DaysIntervalStringFormat" Value="{}{0:dd-MMM}"></Setter>
<Setter Property="RenderTransformOrigin" Value="0.80,0.20"></Setter>
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="-90"></RotateTransform>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<chartingToolkit:Chart Margin="0" Title="Chart Title">
<chartingToolkit:Chart.DataContext>
<local:MyDataCollection/>
</chartingToolkit:Chart.DataContext>
<chartingToolkit:Chart.Axes>
<chartingToolkit:DateTimeAxis Minimum="{Binding StartDate}" Maximum="{Binding EndDate}" Orientation="X" ShowGridLines="True" AxisLabelStyle="{DynamicResource DateTimeAxisLabelStyle1}"/>
</chartingToolkit:Chart.Axes>
<chartingToolkit:LineSeries DependentValuePath="Y" IndependentValuePath="X" ItemsSource="{Binding}"/>
</chartingToolkit:Chart>
</Grid>
Chart:
Here's what I did using the WPF Toolkit Source for reference.
I created a custom class deriving from DateTimeAxis, then overrode the "GetPlotAreaCoordinate" method. The DateTimeAxis.Render() calls that method three times with the same list of "DateTime" values, once for the MajorTickmarks, once for MinorTickmarks, and once for the date label. There were no minor tickmarks in the list, so the method was actually only getting called twice. I just keep a list of the values that have been evaluated and assume that if it's in the list it's already done the tickmarks and is now doing the Labels.
class CustomDateTimeAxis : DateTimeAxis
{
List<object> _valueList = new List<object>();
UnitValue prevBaseValue;
protected override UnitValue GetPlotAreaCoordinate(object value, Range<IComparable> currentRange, double length)
{
_valueList.Add(value);
UnitValue baseValue = base.GetPlotAreaCoordinate(value, currentRange, length);
int valueCount = _valueList.Count((x) => x.Equals(value));
if (valueCount == 2)
return new UnitValue(baseValue.Value + 27, baseValue.Unit);
prevBaseValue = baseValue;
return baseValue;
}
protected override void Render(Size availableSize)
{
base.Render(availableSize);
_valueList.Clear();
}
}
"27" is just a number I was trying out. You might want to play with that to see what works best for you.
return new UnitValue(baseValue.Value + 27, baseValue.Unit);
I created a Margin-Converter:
public class MarginConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var dateTimeAxis = values[0] as DateTimeAxis; ;
var actualAxisLength = values[1] as double?;
var actualMaximum = values[2] as DateTime?;
var actualMinimum = values[3] as DateTime?;
if (dateTimeAxis == null ||
!dateTimeAxis.Interval.HasValue ||
!actualAxisLength.HasValue ||
!actualMaximum.HasValue ||
!actualMinimum.HasValue)
return null;
double xMargin = 0;
var interval = dateTimeAxis.Interval.Value;
var timeSpan = actualMaximum.Value - actualMinimum.Value;
var timeSpanInDays = timeSpan.TotalDays;
if (dateTimeAxis.IntervalType == DateTimeIntervalType.Months)
{
xMargin = 30 * interval * actualAxisLength.Value / timeSpanInDays;
}
else if (dateTimeAxis.IntervalType == DateTimeIntervalType.Days)
{
xMargin = interval * actualAxisLength.Value / timeSpanInDays;
}
return new Thickness(xMargin, 10, 0, -30);
}
public object[] ConvertBack(object value, System.Type[] targetType, object parameter, CultureInfo culture)
{
return null;
}
}
called the X-Axis 'SharedXAxis' and used the converter like this:
<Setter Property="Margin">
<Setter.Value>
<MultiBinding Converter="{StaticResource MarginConv}">
<Binding ElementName="SharedXAxis"/>
<Binding ElementName="SharedXAxis" Path="ActualWidth"/>
<Binding ElementName="SharedXAxis" Path="ActualMaximum"/>
<Binding ElementName="SharedXAxis" Path="ActualMinimum"/>
</MultiBinding>
</Setter.Value>
Imo this should be full dynamic.
The Top- and Bottom-Values of the Thickness of the Margin-Converter ('10' and '-30' in my case) as well as the Bottom-Value of the Padding of the Chart itself have to be adjusted, I don't know why.

Exception in MultiBinding when Application.DispatcherUnhandledException is registered

<UserControl.Resources>
<DataTemplate x:Key="EditCardNonBuffer">
...
...
<ComboBox.SelectedValue>
<MultiBinding Mode="TwoWay" Converter="{StaticResource ingredientRowToTypeIDConverter}">
<Binding Path="GridIngredient.IngredientIngredientTypeRow" />
<Binding Path="GridIngredient.IngredientStockRowByIngredientStockGridIngredient" />
</MultiBinding>
</ComboBox.SelectedValue>
...
...
</DataTemplate>
<DataTemplate x:Key="EditCardBuffer">
...
...
<ComboBox.SelectedValue>
<MultiBinding Mode="TwoWay" Converter="{StaticResource ingredientRowToTypeIDConverter}">
<Binding Path="GridIngredient.IngredientIngredientTypeRow" />
<Binding Path="GridIngredient.IngredientStockRowByIngredientStockGridIngredient" />
</MultiBinding>
</ComboBox.SelectedValue>
...
...
</DataTemplate>
</UserControl.Resources>
<Border BorderBrush="Black" BorderThickness="1" Background="White" Margin="2,-4,2,0" Visibility="{Binding GridIngredient.IsEditMode, Converter={StaticResource GlobalBooleanToVisibilityConverter}}">
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding GridIngredient.IngredientIngredientTypeRow.IngredientTypeRow.IsBuffer}" Value="False">
<Setter Property="ContentTemplate" Value="{StaticResource EditCardNonBuffer}" />
</DataTrigger>
<DataTrigger Binding="{Binding GridIngredient.IngredientIngredientTypeRow.IngredientTypeRow.IsBuffer}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource EditCardBuffer}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</Border>
Converter:
public class IngredientRowToTypeIDConverter : IMultiValueConverter
{
private SystemDataSet _dataSet;
public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture )
{
if( values.Length > 0 && values[ 0 ] is SystemDataSet.IngredientIngredientTypeRow )
{
var row = (SystemDataSet.IngredientIngredientTypeRow) values[ 0 ];
_dataSet = _dataSet ?? (SystemDataSet) row.Table.DataSet;
return row.IngredientTypeID;
}
else
MessageBox.Show( "just for debugging" );
return values;
}
public object[] ConvertBack( object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture )
{
if( value is int && _dataSet != null )
{
var ingredientTypeID = (int) value;
var ingredient = _dataSet.IngredientIngredientType.Where( r => r.IngredientTypeID == ingredientTypeID ).OrderBy( r => r.IngredientRow.LongName ).First();
var ingredientStock = ingredient.IngredientTypeRow.IsBuffer ? ingredient.IngredientRow.IngredientStockRowByDefaultBuffer : ingredient.IngredientRow.IngredientStockRowByDefaultNonBuffer;
return new object[] { ingredient, ingredientStock };
}
else
MessageBox.Show( "just for debugging" );
return new object[] { value };
}
}
Following exception is caught by Application.DispatcherUnhandledException event when I change selected value of combo box.
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
at System.Collections.Generic.List`1.get_Item(Int32 index)
at System.Windows.Data.MultiBindingExpression.UpdateSource(Object convertedValue)
at System.Windows.Data.BindingExpressionBase.UpdateValue()
at System.Windows.Data.BindingExpressionBase.Dirty()
at System.Windows.Data.BindingExpressionBase.SetValue(DependencyObject d, DependencyProperty dp, Object value)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetCurrentValueInternal(DependencyProperty dp, Object value)
at System.Windows.Controls.Primitives.Selector.UpdatePublicSelectionProperties()
at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()
at System.Windows.Controls.Primitives.Selector.SelectionChanger.SelectJustThisItem(ItemInfo info, Boolean assumeInItemsCollection)
at System.Windows.Controls.ComboBoxItem.OnMouseLeftButtonUp(MouseButtonEventArgs e)
But I don't get it when the global exception handler event is not registered.
EDIT:
Notice that one of the bound values of combo box is also bound to a data trigger of the content control to change its data template. The exception ONLY happens when the change in combo box is supposed to change the template as well. The ContentTemplate changes successfully. But why the exception?

How do I create a ProgressBar which is hidden when the Value is 0?

The following doesn't quite work (ProgressValue is a value set in DataContext.)
<StatusBarItem Grid.Column="1">
<StatusBarItem.Resources>
<Style TargetType="ProgressBar">
<Style.Triggers>
<DataTrigger Binding="{Binding ProgressValue}" Value="0">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StatusBarItem.Resources>
<ProgressBar Value="{Binding ProgressValue}" Grid.Column="1" Width="80" Height="13">
</ProgressBar>
</StatusBarItem>
Try setting the ProgressBar's Visibility property in its ValueChanged event:
private void progressBar1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
progressBar1.Visibility = (progressBar1.Value == 0) ? Visibility.Hidden : Visibility.Visible;
}
Try specifying a Minimum (and Maximum) value. After setting those it seems to work for my version of your code.
With this XAML:
<StatusBarItem x:Name="Feedback" Grid.Row="1">
<StatusBarItem.Resources>
<Style TargetType="ProgressBar">
<Style.Triggers>
<DataTrigger Binding="{Binding}" Value="0">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StatusBarItem.Resources>
<ProgressBar Value="{Binding Mode=OneWay}" Minimum="0" Maximum="10" Grid.Column="1" Width="80" Height="13">
</ProgressBar>
</StatusBarItem>
and this code in the constructor of MainWindows.xaml.cs (for testing purposes only)
int value = 10;
public MainWindow()
{
InitializeComponent();
Feedback.DataContext = value;
Timer t = new Timer(500);
t.Elapsed += (s, e) =>
{
if (value > 0) Dispatcher.Invoke(new Action(() => { Feedback.DataContext = --value; }));
else t.Stop();
};
t.Start();
}
I get the progress bar to go from 10 down to 0 at which point the progress bar disappears.
Example XAML:
<ProgressBar>
<ProgressBar.Resources>
<src:DoubleToVisibilityConverter x:Key="_doubleToVisibilityConverter" />
</ProgressBar.Resources>
<ProgressBar.Visibility>
<Binding
RelativeSource="{RelativeSource Self}"
Path="Value"
Converter="{StaticResource _doubleToVisibilityConverter}"
/>
</ProgressBar.Visibility>
</ProgressBar>
And code:
public class DoubleToVisibilityConvertor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double input = 0;
if (value is double)
{
input = (double)value;
}
else if (value is int)
{
input = (int)value;
}
else if (value is string) // Useful if input of converter is written in XAML
{
if (!double.TryParse((string)value, out input))
return Binding.DoNothing;
}
else
{
return Binding.DoNothing;
}
return (input > 0 ? Visibility.Visible : Visibility.Collapsed);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}
Disclaimer: written from memory, not compiled or tested.

Categories

Resources