2

(在任何人问之前,标题是正确的:我的代码仅在 Blend 的设计时工作,而迄今为止最常见的情况正好相反:o)

在 Expression Blend 中设计一个DataTemplate时,我可以看到我的DataTriggers工作正常,我的示例 ViewModel 为电池电量生成一个随机值,并且边框宽度和背景颜色都相应地显示,或者在其BatteryLevelTemplate本身中,或者在另一个包含大量具有各自(随机)电池电量的设备,以及设计时 DataContext。

这是 Expression Blend 的屏幕截图:

在此处输入图像描述

这里是正在运行的应用程序的屏幕截图。请注意,虽然两者都使用与 DataContext 完全相同的类(但作为 Blend 中的设计时),但在运行时仅应用默认的 RedBattery 颜色设置器,即使值本身(也会影响宽度)变化:

在此处输入图像描述

以下是相关的代码部分:

                    <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();
    }
}

更新(使用 Contango 提供的有价值的 Snoop 提示):

我“窥探”了BatteryCharge(Border) 元素,发现了一件有趣的事情:

  • Width受多值元素绑定影响的属性工作正常,并显示在“本地”的绿色阴影行中;
  • 另一方面,该Background属性不工作,不出所料地显示为Style默认红色值。这个不是“DataTriggered”。

在此处输入图像描述

我现在的疑问是我应该如何使用 Snoop(或其他任何东西)来找出未应用 DataTrigger 的原因。

4

2 回答 2

3

我“偶然”发现了这个问题,下面是解释:

  1. 我安装了 Snoop、TriggerTracing和 WPF Inspector 来检查我的 DataTriggers 应用的属性,发现 DataConverter 提供的比较总是 False;
  2. 然后我在 DataConverter 中设置了一个断点,例如,ConverterParameter 提供的字符串“0.75”被 Double.Parsed 为 75.0;
  3. 然后我意识到我现在的语言是pt-BR,小数点分隔符是逗号而不是点。然后我更改了转换器,将 InvariantCulture 参数添加到 Double.Parse。现在它起作用了!

    double limite = double.Parse((string)parameter, CultureInfo.InvariantCulture );

于 2015-05-25T14:43:56.873 回答
0

您的运行时 DataContext 设置不正确,因此您的代码无法在运行时绑定到正确的属性。

请注意,运行时 DataContext 与设计时 DataContext 完全分离,并使用不同的 XAML 来设置运行时 DataContext。

我建议使用 Snoop 来解决问题,您可以使用它来标记由于运行时 DataContext 错误而导致的绑定错误,请在此处查看我的答案:

ReSharper WPF 错误:“由于未知 DataContext,无法解析符号“MyVariable””

于 2015-05-22T21:31:27.680 回答