2016-06-28 4 views
2

Так что я только что присоединился к команде Windows Phone, где они, как правило, чтобы сделать что-то вдоль линий этого:Скрыть элементы против DataTriggers

<Image Width="74" 
     Height="74" 
     Source="ms-appx:///Assets/ImageCatagory/shoot icon.png" 
     Visibility="{Binding SomeBoolParameter, 
     Converter={StaticResource InvertedBoolToVisibilityConverter}}" /> 
<Image Width="74" 
     Height="74" 
     Source="ms-appx:///Assets/ImageCatagory/shoot icon disabled.png" 
     Visibility="{Binding SomeBoolParameter, 
     Converter={StaticResource BoolToVisibilityConverter}}" /> 

Я посмотрел его и подумал про себя: дублирования кода, загрузка 2 элементов в пользовательский интерфейс, который (хотя и второстепенный) загружает ненужную память - зачем загружать оба изображения, когда вам нужно только одно в любой момент?

Я изменил его выглядеть следующим образом:

<Image x:Name="HelperButtonIcon" 
     Margin="19 0"> 

     <i:Interaction.Behaviors> 

      <core:DataTriggerBehavior Binding="{Binding SomeBoolParameter}" 
             ComparisonCondition="Equal" 
             Value="True"> 

        <core:ChangePropertyAction PropertyName="Source" 
               TargetObject="{Binding ElementName=HelperButtonIcon}" 
               Value="ms-appx:///Assets/ImageCatagory/helper icon on.png" /> 

      </core:DataTriggerBehavior> 
      <core:DataTriggerBehavior Binding="{Binding SomeBoolParameter}" 
             ComparisonCondition="Equal" 
             Value="False"> 

        <core:ChangePropertyAction PropertyName="Source" 
               TargetObject="{Binding ElementName=HelperButtonIcon}" 
               Value="ms-appx:///Assets/ImageCatagory/helper icon off.png" /> 

      </core:DataTriggerBehavior> 

</i:Interaction.Behaviors> 

С помощью DataTriggers я использую только 1 элемент в любой момент времени, который кажется более эффективным для меня. Тем не менее, код получает завышенное немного для совсем малого, и, кроме того, я немного боюсь за проблемы с производительностью, связанные с загрузкой и переключением изображений. Я не нашел ничего относительно лучших практик в этом вопросе, и хотя я уверен, что это лучше, я бы хотел быть уверенным. Вопрос в следующем:

Является ли использование триггеров данных для переключения свойств этих идентичных элементов лучше, чем переключатель видимости?

+0

Обратите внимание, что вы также можете установить значение по умолчанию для одного из этих URL-адресов в стиле и сделать только один источник данных для второго – nkoniishvt

ответ

0

Я хотел бы использовать ни один из вариантов, и вместо того, чтобы иметь этот логин в вид-модели:

public bool SomeBoolParameter 
{ 
    get { /* ... */ } 
    set 
    { 
     //... 
     OnPropertyChanged("SomeBoolParameter"); 
     OnPropertyChanged("ImageUrl"); 
    } 
} 

public string ImageUrl 
{ 
    get 
    { 
     return SomeBoolParameter ? "..." : "..."; 
    } 
} 
<Image Source="{Binging ImageUrl}" /> 

Кроме того, почему бы не использовать встроенный в DataTriggers, если вы ничего не делаете фантазии? Предпочитаете вариант DataTrigger, если бы мне пришлось выбирать между двумя вашими вариантами, он логически чище. Я не думаю, что вы должны слишком беспокоиться о памяти, если это не станет проблемой.

+0

. Проблема, которую я нахожу с вашим предложением, заключается в том, что она дает контроль над ViewModel над пользовательским интерфейсом. VM якобы «не знает/ухаживает» за ним, поэтому он держит URL-адреса URL изображения одним из принципов шаблона MVVM. – MichaelThePotato

+1

@MichaelThePotato: модель представления - это модель для представления; он должен описывать данные вида, поэтому он держит данные, такие как URL-адреса изображений, отлично. –

+0

Не совсем.URL-адрес изображения связан с дисплеем и не связан с данными. Пользовательский интерфейс сам должен определить, какое изображение будет отображаться в любой момент времени, используя текущее состояние виртуальной машины. дело не в том, чтобы работать с такими вещами. Поэтому для виртуальной машины нецелесообразно хранить такие объекты, как URL-адреса изображений для отображения пользовательского интерфейса. – MichaelThePotato

0

Этот вопрос будет довольно спорным. Лично я считаю, что первоначальная реализация лучше. Я объясняю это следующим образом:

  1. Современные оперативные запоминающие устройства вполне способны хранить миллионы миниатюр.
  2. Если вы постоянно меняете значение SomeBoolProperty, вы будете делать много раз операцию чтения с жесткого диска. Диск IO относительно медленнее. Также изображения будут находиться в вашей ОЗУ каждый раз, когда ваш источник Image изменяется, и сборщик мусора должен работать усерднее.
  3. Вы немного усложняете, чтобы кто-то другой понял ваш код, когда кто-то другой возьмет ваш проект в будущем.

Конечно, если сценарий имеет предварительную загрузку 1000 изображений, ожидая, пока конвертер скажет им, какой из 1000 должен быть видимым, тогда ваше решение вполне разумно.

+0

WPF делает некоторое кэширование изображений, на самом деле. –

+0

@ H.B. Но если кеширование сохраняется на жестком диске, оно все равно так же хорошо, как чтение из исходного источника. Если он находится в ОЗУ, то он так же хорош, как и исходное решение. – Jai

+0

Основная причина, по которой я хотел переписать деталь в первую очередь, объяснялась тем, что это был один из многих случаев в проекте дублирования кода. Очевидно, что дублирование кода - это очень плохо, он удваивает работу во время обслуживания и во время разработки (приложение еще не живое). Так что это был всего лишь небольшой случай, когда я мог избавиться от такой плохой вещи. – MichaelThePotato

Смежные вопросы