绑定文本块,以便在一个页面上对变量进行一次更改反映在UI中

时间:2010-12-26 08:19:19

标签: .net wpf vb.net xaml xbap

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

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

用户输入他们的电子邮件进行登录(无需密码,只需要发送电子邮件以识别,它是一个内部应用程序,因此用户不需要密码,甚至用户也不需要密码。)

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

我希望在用户登录时更改ui_txbUserName,如果他/她从一个帐户注销到另一个帐户,则更新。我看过INotifyPropertyChanged和Dependency Properties,我只是不确定如何去做!任何帮助都是极好的!!!

谢谢!

UsingOfficerID - 当一个人登录时设置的全局变量,它在应用程序中的所有位置使用。

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

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

这些都没有反映在UI中

2 个答案:

答案 0 :(得分:1)

好的,我假设你没有使用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中调用你的helper方法来调用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具有forename和surname属性,您可以使用以下命令在视图中绑定它:

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

现在每当CurrentUser发生变化时,您的UI都会更新。请注意,如果您希望在用户类型的属性发生更改时更新UI(例如forename),那么IUser的具体实现也需要实现INotifyPropertyChanged。

答案 1 :(得分:0)

好的,我想我会添加另一个解决您的示例应用程序细节的答案。我已经看了一下样本,但代码似乎有点处于不稳定的状态!首先,你没有在任何地方设置MainWindow的DataContext(视图),这应该被设置为你的视图模型的一个实例(UserViewModel.vb,虽然我会考虑重命名视图或视图模型,以便它们是例如MainView和MainViewModel)。

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

// MainWindow.xaml.vb
Class MainWindow

  Public Sub New()

      InitializeComponent()

      Me.DataContext = New UserViewModel()

  End Sub

End Class

现在,在UserViewModel中,您有一个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(“地址”)?也许这是一个复制/粘贴错误,但字符串值必须与其值已更改的属性的名称匹配,因为绑定引擎将使用反射来检索新的属性值。

最后,我刚刚更改了MainWindow.xaml中的绑定表达式

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

因为未在TextBlock上显式设置DataContext,所以它将使用视图的DataContext(UserControl),该视图设置为UserViewModel的实例。这意味着它将绑定到DataContext上的UserName属性,这是您想要的。要测试它,您可以在UserViewModel的构造函数中设置Me.UserName =“Something”的值。

希望你能看到绑定对字符串的作用,你可以找出你需要去哪里使用它的用户类型。