Привязка текстового блока, чтобы одно изменение переменной на одной странице отражалось в пользовательском интерфейсе - PullRequest
1 голос
/ 26 декабря 2010

Базовая раскладка (VB.NET и WPF / XBAP) :

У меня есть MainPage - mainpage.xaml Внутри MainPage у меня есть фрейм, который содержит другие страницы. Первая страница, которая загружается автоматически - это LogIn - LogIn.xaml

Пользователь вводит свою электронную почту для входа в систему (пароль не требуется, просто электронная почта для идентификации, это внутреннее приложение, поэтому пароли не требуются или даже не требуются пользователями).

В MainPage.xaml заголовок должен иметь текстовый блок «Hello» (имя: ui_txbUserName). На странице входа есть метод, который при отправке получает идентификатор пользователя (по другим причинам и сохраняет его) и имя пользователя.

Я хочу изменить имя ui_txbUserName, когда человек входит в систему и обновляет его, если он / она выходит из одной учетной записи в другую. Я смотрел на свойства INotifyPropertyChanged и Dependency, и я просто не уверен, как это сделать! Любая помощь будет потрясающей !!!

Спасибо!

UsingOfficerID - это глобальная переменная, устанавливаемая при входе пользователя в систему, которая используется повсеместно в приложении.

Я попробовал следующее в примере приложения:

http://www.2shared.com/file/68enzucg/SampleApp.html

Ничего из этого не отражено в интерфейсе пользователя

Ответы [ 2 ]

1 голос
/ 27 декабря 2010

Хорошо, я предполагаю, что вы не используете шаблон проектирования MVVM для создания своего приложения? Если нет, то я предлагаю вам взглянуть на это, поскольку это дает много преимуществ, в частности разделение проблем и тестируемость.

В MVVM вашим представлениям (файлам .xaml) будет задан свой DataContext в качестве модели представления. Итак, для вас главная страница, я бы имел MainViewModel.cs и MainView.xaml. http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html - хорошая статья о шаблоне проектирования MVVM.

Ваша модель представления должна затем реализовать INotifyPropertyChanged (вы не должны использовать свойства зависимостей в моделях представления). У этого интерфейса есть одно событие PropertyChanged, которое вы можете вызвать для уведомления любых клиентов (в данном случае клиента привязки WPF) о том, что произошло изменение в вашем свойстве. Это делает недействительной привязку и вызывает повторный вызов метода получения свойств для получения нового значения.

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

В вашем случае MainViewModel потребуется ссылка на текущего пользователя, например, как открытое свойство типа IUser, которое в установщике вызывает ваш вспомогательный метод для вызова события PropertyChanged.

private IUser currentUser;

public IUser CurrentUser
{
  get
  {
    return this.currentUser;
  }

  set
  {
    this.currentUser = value;
    RaisePropertyChanged("CurrentUser");
  }
}

// constructor
public MainViewModel(IUser currentUser)
{
  this.CurrentUser = currentUser;
}

protected void RaisePropertyChanged(string propertyName)
{
  PropertyChangedEventHandler handler = PropertyChanged;
  if (handler != null)
  {
    handler(this, new PropertyChangedEventArgs(propertyName));
  }
}

Предполагая, что IUser имеет свойства имени и фамилии, вы привязываетесь к нему в своем представлении, используя:

<TextBlock>
  <TextBlock.Text>
    <MultiBinding StringFormat="Hello {0} {1}">
      <Binding Path="CurrentUser.FirstName" />
      <Binding Path="CurrentUser.LastName" />
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

Теперь, когда изменяется CurrentUser, ваш пользовательский интерфейс будет обновляться. Обратите внимание, что если вы хотите, чтобы пользовательский интерфейс обновлялся при изменении свойства пользовательского типа (например, имя), тогда вашей конкретной реализации IUser также потребуется реализация INotifyPropertyChanged.

0 голосов
/ 28 декабря 2010

Хорошо, я подумал, что добавлю еще один ответ, который касается специфики вашего примера приложения.Я посмотрел пример, но код, кажется, немного изменчив!Во-первых, вы нигде не устанавливали DataContext из MainWindow (представление), для этого следует установить экземпляр вашей модели представления (UserViewModel.vb, хотя я бы рассмотрел возможность переименования либо представления, либо модели представления, чтобы они, например,MainView и MainViewModel).

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

// MainWindow.xaml.vb
Class MainWindow

  Public Sub New()

      InitializeComponent()

      Me.DataContext = New UserViewModel()

  End Sub

End Class

Теперь в вашем UserViewModel у вас есть свойство UserName, но, похоже, оно возвращает и устанавливает свойство username объекта User.Несмотря на то, что пользовательский объект никогда, кажется, нигде не установлен.Для простоты я просто использовал вместо этого строку с новым вспомогательным полем:

Private _username As String
Public Property UserName() As String
     Get
         Return _username
     End Get
     Set(ByVal Value As String)
         _username = Value
         MyBase.OnPropertyChanged("UserName")
     End Set
End Property

Первоначально вы по какой-то причине вызывали MyBase.OnPropertyChanged ("Address") ??Возможно, это была ошибка копирования / вставки, но строковое значение должно совпадать с именем свойства, значение которого изменилось, поскольку механизм привязки будет использовать отражение для получения нового значения свойства.

Наконец, я только что изменилвыражение привязки в MainWindow.xaml

<TextBlock Grid.Row="0" Text="{Binding UserName}" />

Поскольку DataContext явно не задан для TextBlock, он будет использовать DataContext представления (UserControl), который установлен в экземпляр UserViewModel.Это означает, что он будет привязан к свойству UserName в этом DataContext, что вам нужно.Чтобы проверить это, вы можете установить значение Me.UserName = "Something" в конструкторе UserViewModel.

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

...