2015-05-22 6 views
2

(до кто-нибудь спросит, название прав: У меня есть код работает только при дизайн времени в Blend, в то время как наиболее распространенный на сегодняшний день было бы наоборот: о)Стиль DataTriggers, работающий во время разработки, но не во время выполнения - почему?

При проектировании DataTemplate в выражении Blend, я вижу, что мой DataTriggers работает отлично, мой образец ViewModel генерирует случайное значение для уровня батареи, и соответственно отображает ширину полосы и цвет фона, либо в самом BatteryLevelTemplate, либо на другой панели, содержащей множество устройств с их (случайный) уровень заряда батареи, с данным DataContext.

Вот скриншот из Expression Blend:

enter image description here

А вот скриншот от запущенного приложения. Обратите внимание на то, что, хотя оба они используют точно тот же класс, что и DataContext (но как время разработки в Blend), во время выполнения применяется только стандартный набор цветов RedBattery, даже если значение самого значения (которое также влияет на ширину) меняется:

enter image description here

А вот соответствующие кодовые части:

    <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 (используя ценный Snoop совета по контанго):

I "слежения за ними" элемент BatteryCharge (Border), и обнаружил интересную вещь:

  • Width недвижимости, который зависит от привязки многозначных элементов, работает нормально и отображается в «локальном», зеленом штриховом ряду;
  • С другой стороны, свойство Background, которое не работает, отображает неудивительно, как Style с по умолчанию красным значением. Это не «DataTriggered».

enter image description here

Мои сомнения в том, как я должен использовать Snoop (или что-нибудь еще), чтобы выяснить, почему DataTrigger не применяется.

ответ

0

Время выполнения DataContext не задано правильно, поэтому ваш код не может привязываться к правильным свойствам во время выполнения.

Обратите внимание, что время выполнения DataContext полностью зависит от времени разработки DataContext и использует различные XAML для установки DataContext среды выполнения.

Я бы рекомендовал использовать Snoop, чтобы решить эту проблему, вы можете использовать его, чтобы флаг вверх ошибки связывания из-за плохого выполнения DataContext см мой ответ здесь:

ReSharper WPF error: "Cannot resolve symbol "MyVariable" due to unknown DataContext"

+1

Бу как же все другое свойство настроено правильно? Работает красный цвет фона по умолчанию, установленный в установщике по умолчанию из datafgrid, из стиля, из шаблона. То есть, обязательно работает datacontext, работает дата-шаблон, стиль работает, и сеттер работает, только триггеры _data_, по-видимому, не работают ... – heltonbiker

+0

Хорошая точка. Обычно такие вещи возвращаются к плохому DataContext где-то. Можете ли вы запустить Snoop и проверить, правильно ли настроены все DataContext во время выполнения? См. Окончательную ссылку в моем ответе. – Contango

+0

К сожалению, у меня нет ReSharper или Snoop. Завтра я планирую сделать пошаговое тестирование, чтобы узнать, узнаю, где проблема, спасибо. – heltonbiker

1

я обнаружил проблему «случайно », и здесь идет объяснение:

  1. Я установил Snoop, TriggerTracing, а также WPF инспектор, чтобы проверить свойства применяемых моих DataTriggers, и узнал, что сравнение обеспечивается DataConverter всегда Ложное;
  2. Затем я поставил перебор внутри DataConverter, чтобы обнаружить, что, например, строка «0.75», предоставленная ConverterParameter, была Double.Parsed как 75.0;
  3. Тогда я понял, что мой текущий язык - pt-BR, а десятичный разделитель - вместо запятой. Затем я сменил конвертер, добавив параметр InvariantCulture в Double.Parse. И теперь это работает!

    двойной Limite =() параметр (строка, CultureInfo.InvariantCulture) double.Parse;

+0

Brilliant !!! Приятно слышать, что это решено. – Contango