Есть три соображения здесь:
Рассмотрения 1: Свойство не имеет уведомления об изменении
Некоторые привязки данных могут быть оценены во время вызова InitializeComponent(), и другие оцениваются позже. Вы запрашиваете возможность установки CanSeePhotos после того, как InitializeComponent() уже возвращен. Если у вас нет уведомления об изменении, любое связывание, полученное в процессе InitializeComponent(), будет иметь исходное значение и не будет обновляться. После каждого последующего связывания (например, при приоритете DataBind) появится новое значение. Чтобы сделать эту работу во всех случаях, вам нужно какое-то уведомление об изменении.
Использование свойства NET Framework, объявленного с помощью функции "{get; set;}", не будет работать, потому что свойство не имеет механизма, чтобы уведомить кого-либо, если его значение изменилось. На самом деле существует два очень простых способа получить уведомление от стандартного свойства NET Framework (MarshalByRefObject и перезаписи IL), но они слишком сложны для вашей ситуации.
Рассмотрение 2: Свойство статичен
NET Framework имеет несколько механизмов уведомления об изменении свойств (DependencyProperty, INotifyPropertyChanged и т.д.), но ни один из встроенных механизмов не поддерживает уведомление об изменении на статических свойствах.Таким образом, вы не можете использовать статическое свойство для этого без создания нового механизма для сигнализации изменений (например, у вас может быть объект, который обертывает свойство).
Рассмотрение 3: DataTriggers разделяют один Binding
При настройке видимости вы строите новый Binding каждый раз, поэтому он получает последнюю ценность LoggedInUser.CanSeePhotos.
При создании DataTrigger WPF создает единственное связывание при загрузке триггера и использует его для каждого объекта. Это привязка создается, когда загружается ресурсный словарь, содержащий DataTrigger, который, вероятно, при запуске приложения, поэтому он всегда будет получать значение по умолчанию для CanSeePhotos. Это связано с тем, что Source = назначает фактический объект в привязку (его вычисление не откладывается). Поэтому каждое связывание создается с помощью Source = true или Source = false.
Рекомендуемое решение
Используйте DependencyObject с DependencyProperty и ссылаться на него статическое свойство, например:
public class LoggedInUser : DependencyObject
{
// Singleton pattern (Expose a single shared instance, prevent creating additional instances)
public static readonly LoggedInUser Instance = new LoggedInUser();
private LoggedInUser() { }
// Create a DependencyProperty 'CanSeePhotos'
public bool CanSeePhotos { get { return (bool)GetValue(CanSeePhotosProperty); } set { SetValue(CanSeePhotosProperty, value); } }
public static readonly DependencyProperty CanSeePhotosProperty = DependencyProperty.Register("CanSeePhotos", typeof(bool), typeof(LoggedInUser), new UIPropertyMetadata());
}
Этот класс всегда будет иметь один экземпляр и экземпляр будет доступен как LoggedInUser.Instance. Так что это нечто вроде статического класса. Разница заключается в том, что LoggedInUser.Instance имеет DependencyProperty, поэтому, когда вы изменяете свойство, он может уведомить всех заинтересованных сторон. Связывание WPF будет регистрироваться для этого уведомления, поэтому ваш пользовательский интерфейс будет обновлен.
Код выше будет использоваться, как это в XAML:
Visibility="{Binding CanSeePhotos, Source={x:Static LoggedInUser.Instance}, Converter=...
В коде-за, если вам нужно получить доступ к CanSeePhotos было бы, например:
LoggedInUser.Instance.CanSeePhotos = true;
Hi Ray, я понимают свойства зависимостей, но не хотят их использовать, потому что CanSeehotos никогда не будет изменен после получения данных в первый раз. Что меня отталкивает, так это то, что привязка видимости объекта к статическому свойству в DataTemplate отлично работает, но он не работает в DataTrigger DataTemplate. Спасибо за Ваш ответ. Я попробую. –
Спасибо за разъяснение вашего вопроса. Я добавил новую «Проблему 3» к моему ответу, чтобы выяснить, почему DataTrigger не работает, а также некоторое объяснение в «Задаче 1», чтобы объяснить, почему вам требуется уведомление об изменении в вашем сценарии. Надеюсь это поможет. –
+1, но вам действительно не нужен DependencyProperty, IMHO, использующий INotifyPropertyChanged, лучше –