Reputation: 27575
(before anyone asks, the title is right: I have code working only at design time in Blend, while the most common by far would be the opposite :o )
While designing a DataTemplate
in Expression Blend, I can see my DataTriggers
working fine, my sample ViewModel generates a random value for the level of a battery, and both border width and background color display accordingly, either in the BatteryLevelTemplate
itself, and another panel containing a lot of devices with their respective (random) battery level, with a design-time DataContext.
Here is a screenshot from Expression Blend:
And here a screenshot from the running application. Notice that, while both use exactely the same class as DataContext (but as design time in Blend), at runtime only the default RedBattery color setter is applied, even if the value itself (which also affects width) varies:
And here are the relevant code parts:
<Border.Width>
<MultiBinding Converter="{StaticResource NormalValueConverter}" FallbackValue="10">
<Binding Path="NívelBateria"/>
<Binding Path="ActualWidth" ElementName="BatteryChargeContainer"/>
</MultiBinding>
</Border.Width>
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{StaticResource BatteryRed}"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding NívelBateria, Converter={StaticResource ValorMaiorQue}, ConverterParameter=0.25}" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{StaticResource BatteryOrange}"/>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding NívelBateria, Converter={StaticResource ValorMaiorQue}, ConverterParameter=0.5}" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{StaticResource BatteryYellow}"/>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding NívelBateria, Converter={StaticResource ValorMaiorQue}, ConverterParameter=0.75}" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="{StaticResource BatteryGreen}"/>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
============
<DockPanel x:Name="PainelSetupsSensores" Background="#FFB8E6E8"/>
<DockPanel x:Name="PainelSensoresDisponiveis" Background="#FFF0F0F0"
Grid.RowSpan="2" Grid.Column="1"
DataContext="{Binding ReceiverAtivo}"
d:DataContext="{d:DesignInstance Type=local:ReceiverSimulado, IsDesignTimeCreatable=True}">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Sensores}" Margin="10">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</DockPanel>
====================
class ValorMaiorQue : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double valor = (double)value;
double limite = double.Parse((string)parameter);
return valor > limite;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
UPDATE (using the valuable Snoop tip by Contango):
I "snooped" the BatteryCharge
(Border) element, and found out an interesting thing:
Width
property, which is affected by a Multi Value Element Binding, is working fine and displays in a "Local", green-shaded row;Background
property, which is not working, displays unsurprisingly as Style
with the default red value. This one is not being "DataTriggered".My doubt now is how I am supposed to use Snoop (or anything else) to find out why the DataTrigger is not being applied.
Upvotes: 2
Views: 1149
Reputation: 27575
I discovered the problem "accidentally", and here goes the explanation:
Then I realized that my current language is pt-BR, and the decimal separator is comma instead of dot. Then I changed the converter, adding an InvariantCulture parameter to Double.Parse. And now it works!
double limite = double.Parse((string)parameter, CultureInfo.InvariantCulture);
Upvotes: 3
Reputation: 80192
Your run time DataContext is not being set correctly, so your code can't bind to the correct properties at runtime.
Note that the run time DataContext is completely separate to the design time DataContext, and uses different XAML to setting the runtime DataContext.
I would recommend using Snoop to fix the problem, you can use it to flag up binding errors due to a bad runtime DataContext, see my answer here:
ReSharper WPF error: "Cannot resolve symbol "MyVariable" due to unknown DataContext"
Upvotes: 0