绑定文本块,以便一页上的变量的一项更改反映在 UI 中

发布于 2024-10-09 08:44:02 字数 689 浏览 0 评论 0原文

基本布局(VB.NET和WPF/XBAP)

我有一个MainPage - mainpage.xaml 在主页内,我有一个托管其他页面的框架。自动加载的第一个页面是登录 - LogIn.xaml

用户输入电子邮件进行登录(不需要密码,只需通过电子邮件进行识别,它是内部应用程序,因此用户不需要甚至不需要密码)。

在 MainPage.xaml 上,标题应该有一个“Hello”TexBlock(名称:ui_txbUserName)。登录页面有一个方法,在提交时获取用户 ID(出于其他原因并保存它)和用户名。

我想在该人登录时更改 ui_txbUserName ,并在他/她从一个帐户注销到另一个帐户时进行更新。我已经查看了 INotifyPropertyChanged 和依赖属性,但我只是不知道如何去做!任何帮助都会很棒!

谢谢!

usingOfficerID - 它是一个在用户登录时设置的全局变量,它在应用程序中的各处使用。

我在示例应用程序中尝试了以下内容:

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

这些都没有反映在 UI 中

Basic layout (VB.NET & WPF/XBAP):

I have a MainPage - mainpage.xaml
Inside the MainPage I have a frame that hosts other pages. The first page that is auto loaded is the LogIn - LogIn.xaml

The user enters their email to login (no password required, just email to identify, its an internal app so passwords are not required or even wanted by users).

On MainPage.xaml the header should have a "Hello " TexBlock (name: ui_txbUserName). The LogIn page has a method which on submit gets the UserID (for other reasons and saves it) and the User Name.

I want to change the ui_txbUserName when the person logs in and update if he/she logs out of one account into another. I have looked at INotifyPropertyChanged and Dependency Properties and im just not sure how to go about doing this! Any help would be awesome!!!

Thanks!

UsingOfficerID - its a global variable set when a person logs in, its used all over the place in the application.

I have tried the Following inside the sample app:

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

None of this is reflected in the UI

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

好的,我假设您没有使用 MVVM 设计模式来构建您的应用程序?如果没有,我建议您考虑这样做,因为它提供了很多好处,最显着的是关注点分离和可测试性。

在 MVVM 中,您的视图(.xaml 文件)会将其 DataContext 设置为您的视图模型。因此,对于您的主页,我将有一个 MainViewModel.cs 和 MainView.xaml。 http://csharperimage.jeremylikness.com/2010/04 /model-view-viewmodel-mvvm-explained.html 是一篇关于 MVVM 设计模式的好文章。

然后,您的视图模型应该实现 INotifyPropertyChanged (您不应该在视图模型上使用依赖属性)。该接口有一个名为 PropertyChanged 的​​事件,您可以调用该事件来通知任何客户端(在本例中为 WPF 绑定客户端)您的属性已发生更改。这会使绑定无效,并导致再次调用属性 getter 以检索新值。

通常,与任何 .NET 事件一样,您将创建一个辅助方法来调用该事件,并将已更改的属性名称作为字符串传递给它。请参阅文章中的示例。

在您的情况下,MainViewModel 需要对当前用户的引用,例如作为 IUser 类型的公共属性,它在 setter 中调用您的帮助器方法来调用 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 更改时,您的 UI 都会更新。请注意,如果您希望 UI 在用户类型的属性发生更改(例如名字)时更新,那么 IUser 的具体实现还需要实现 INotifyPropertyChanged。

Ok, I'm assuming that you're not using the MVVM design pattern to build your application? If not, I suggest you have a look into doing so, as it provides many benefits, most notably separation of concerns and testability.

In MVVM, your views (.xaml files) would have their DataContext set as your view model. So, for you main page, I would have a MainViewModel.cs and MainView.xaml. http://csharperimage.jeremylikness.com/2010/04/model-view-viewmodel-mvvm-explained.html is a nice article on the MVVM design pattern.

Your view model should then implement INotifyPropertyChanged (you shouldn't use dependency properties on view models). This interface has one event on it called PropertyChanged which you can invoke to notify any clients (in this case the WPF binding client) that a change to your property has occurred. This invalidates the binding, and causes that properties getter to be called again to retrieve the new value.

Normally, as with any .NET event, you would create a helper method to invoke the event, and pass it the name of the property which has changed as a string. See the article for examples.

In your case, the MainViewModel would need a reference to the current user, e.g. as a public property of type IUser, which in the setter calls your helper method to invoke the PropertyChanged event.

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

Assuming IUser has forename and surname properties, you would bind to it in your view using:

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

Now whenever the CurrentUser changes, your UI will update. Note that if you want the UI to update if a property of the user type changes (e.g. forename), then your concrete implementation of IUser will also need to implement INotifyPropertyChanged.

梦回梦里 2024-10-16 08:44:02

好的,我想我应该添加另一个答案来解决您的示例应用程序的具体问题。我已经查看了示例,但代码似乎有点不稳定!首先,您还没有在任何地方设置 MainWindow (视图)的 DataContext,这应该设置为视图模型的实例(UserViewModel.vb,尽管我会考虑重命名视图或视图模型,以便它们例如主视图和主视图模型)。

您可以通过多种方式设置 DataContext,使用视图优先或视图模型优先方法。开始测试的一种快速方法是在视图的构造函数中:

// MainWindow.xaml.vb
Class MainWindow

  Public Sub New()

      InitializeComponent()

      Me.DataContext = New UserViewModel()

  End Sub

End Class

现在,在 UserViewModel 中,您有一个 UserName 属性,但它似乎返回并设置一个 User 对象 username 属性。即使用户对象似乎从未在任何地方设置过。为了简单起见,我只是使用了一个字符串,而不是一个新的支持字段:

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 上显式设置,所以它将使用设置为 UserViewModel 实例的视图 (UserControl) 的 DataContext。这意味着它将绑定到您想要的 DataContext 上的 UserName 属性。要测试它,您可以在 UserViewModel 的构造函数中设置 Me.UserName = "Something" 的值。

希望您能够了解绑定如何适用于字符串,并且您可以找出需要在哪里才能使其适用于您的 User 类型。

Ok, I thought I'd add another answer which addresses the specifics of your sample application. I've had a look through the sample, but the code seems to be a bit in a state of flux! Firstly, you haven't set the DataContext of MainWindow (the view) anywhere, this should be set to an instance of your view model (UserViewModel.vb, although I would consider renaming either the view or the view model so that they are e.g. MainView and MainViewModel).

You can set the DataContext in several ways, using a view first or view model first approach. One quick way to start testing is in the constructor of your view:

// MainWindow.xaml.vb
Class MainWindow

  Public Sub New()

      InitializeComponent()

      Me.DataContext = New UserViewModel()

  End Sub

End Class

Now, in your UserViewModel, you have a UserName property, but it seems to return and set a User object username property. Even though the user object never seems to be set anywhere. To keep things simple, I just used a string instead with a new backing field:

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

Originally, you had called MyBase.OnPropertyChanged("Address") for some reason?? Maybe this was a copy/paste error, but the string value must match the name of the property whose value has changed, as the binding engine will use reflection to retrieve the new property value.

Finally, I just changed the binding expression in MainWindow.xaml

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

Because the DataContext isn't explicitly set on the TextBlock, it will use the DataContext of the view (UserControl) which is set to an instance of UserViewModel. This means that it will bind to a UserName property on that DataContext which is what you want. To test it, you can set the value of Me.UserName = "Something" in the constructor of the UserViewModel.

Hopefully you can see how the binding works for strings, and you can work out where you need to go to get it working for your User type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文