samedi 9 août 2014

c# - Visualisez une chaîne au lieu d'un nombre décimal selon l'état via la liaison - Stack Overflow


I have a XAML UserControl which only has a Rectangle and a TextBlock. The Text-property is set through binding with a DependencyProperty of type decimal.


XAML:


<UserControl x:Class="UserControls.TotalsDataGridCellContentControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<Grid x:Name="LayoutRoot">
<Rectangle Fill="{Binding IsValid, Converter={StaticResource isValidConverter}, ElementName=Root}"
HorizontalAlignment="Stretch" />
<TextBlock Grid.Column="1"
Text="{Binding Total, ElementName=Root}"
HorizontalAlignment="Right"
Margin="0 2 3 0" />
</Grid>
</UserControl>

C#:


public decimal Total
{
get { return (decimal)GetValue(TotalProperty); }
set { SetValue(TotalProperty, value); }
}

public static readonly DependencyProperty TotalProperty =
DependencyProperty.Register("Total",
typeof(decimal),
typeof(TotalsDataGridCellContentControl),
new PropertyMetadata(TotalChanged));

private static void TotalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}

Now I'm required to show a string like N/A in the TextBlock if some condition is not met. So normally if the condition is met, the value of Total should be displayed in the TextBlock, otherwise a string like N/A.


Is there an easy way to this? Like for example, add another property (string), set the value depending on the condition and bind that property to the TextBlock?


I have heard of StringFormat to display numbers, dates, ... in a specific given format, but I don't think this is of any use for this case.


Thanks in advance.




The following should suit your needs, while (hopefully) being simple enough:


<Label Content="{Binding TestProp}">
<Label.Style>
<Style TargetType="Label">
<Style.Triggers>
<DataTrigger Binding="{Binding TestProp}" Value="12">
<Setter Property="ContentStringFormat" Value="N/A" />
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>

In this example the displayed string changes to "N/A" if value is 12 (though obviously you'd need to set your trigger up differently).




You have the following options:


If your condition can never change (so the only changing thing is the value of Total) you can implement IValueConverter.Convert (you don't need to implement ConvertBack) and determine the return value inside.


return (MeetsCondition((decimal)value)) ? value : "N/A";

xaml usage:


Text="{Binding Total, ElementName=Root, Converter={StaticResource MyValueConverter}}"

But if your condition changes your binding will not be evaluated as long as Total doesn't change. ...and will therefore display the wrong result.


Your second option: introduce a resulting property in your code that is recalculated everytime the condition or the Total changes. Bind Text against it.


private static void TotalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((TotalsDataGridCellContentControl)d).EvaluateCondition();
}

private static void ConditionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((TotalsDataGridCellContentControl)d).EvaluateCondition();
}

Your third option (a bit too "fat" I reckon): Define VisualStates "ConditionEvaluationStates" for "ConditionSatisfied" and "ConditionNotSatisfied" and show different visual elements depending on the state.



I have a XAML UserControl which only has a Rectangle and a TextBlock. The Text-property is set through binding with a DependencyProperty of type decimal.


XAML:


<UserControl x:Class="UserControls.TotalsDataGridCellContentControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<Grid x:Name="LayoutRoot">
<Rectangle Fill="{Binding IsValid, Converter={StaticResource isValidConverter}, ElementName=Root}"
HorizontalAlignment="Stretch" />
<TextBlock Grid.Column="1"
Text="{Binding Total, ElementName=Root}"
HorizontalAlignment="Right"
Margin="0 2 3 0" />
</Grid>
</UserControl>

C#:


public decimal Total
{
get { return (decimal)GetValue(TotalProperty); }
set { SetValue(TotalProperty, value); }
}

public static readonly DependencyProperty TotalProperty =
DependencyProperty.Register("Total",
typeof(decimal),
typeof(TotalsDataGridCellContentControl),
new PropertyMetadata(TotalChanged));

private static void TotalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}

Now I'm required to show a string like N/A in the TextBlock if some condition is not met. So normally if the condition is met, the value of Total should be displayed in the TextBlock, otherwise a string like N/A.


Is there an easy way to this? Like for example, add another property (string), set the value depending on the condition and bind that property to the TextBlock?


I have heard of StringFormat to display numbers, dates, ... in a specific given format, but I don't think this is of any use for this case.


Thanks in advance.



The following should suit your needs, while (hopefully) being simple enough:


<Label Content="{Binding TestProp}">
<Label.Style>
<Style TargetType="Label">
<Style.Triggers>
<DataTrigger Binding="{Binding TestProp}" Value="12">
<Setter Property="ContentStringFormat" Value="N/A" />
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>

In this example the displayed string changes to "N/A" if value is 12 (though obviously you'd need to set your trigger up differently).



You have the following options:


If your condition can never change (so the only changing thing is the value of Total) you can implement IValueConverter.Convert (you don't need to implement ConvertBack) and determine the return value inside.


return (MeetsCondition((decimal)value)) ? value : "N/A";

xaml usage:


Text="{Binding Total, ElementName=Root, Converter={StaticResource MyValueConverter}}"

But if your condition changes your binding will not be evaluated as long as Total doesn't change. ...and will therefore display the wrong result.


Your second option: introduce a resulting property in your code that is recalculated everytime the condition or the Total changes. Bind Text against it.


private static void TotalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((TotalsDataGridCellContentControl)d).EvaluateCondition();
}

private static void ConditionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((TotalsDataGridCellContentControl)d).EvaluateCondition();
}

Your third option (a bit too "fat" I reckon): Define VisualStates "ConditionEvaluationStates" for "ConditionSatisfied" and "ConditionNotSatisfied" and show different visual elements depending on the state.


0 commentaires:

Enregistrer un commentaire