【问题标题】:WPF inherit base propertyWPF 继承基属性
【发布时间】:2018-03-08 05:55:57
【问题描述】:

我正在尝试在我的窗口中传播一个字符串属性以显示标题。

在我的基类中,我使用默认的 get/set 设置了一个公共字符串属性。

在继承基类的窗口中,我尝试使用该属性作为窗口的标题。这失败了。但是,当我弹出一个消息框时,我肯定可以访问该属性。

如何在 WPF 窗口中显示来自基类的字符串属性?

代码:

BaseWindow.cs:

public class BaseWindow : Window
{
  public string AppTitle { get; set; }
  public string AppVersion { get; set; }

  public BaseWindow()
  {
    AppTitle = "My Application";
    AppVersion = "2.1";
  }
  ... 
}

MainWindow.xaml:

<src:BaseWindow x:Class=... >
  <Window.Title>
    <MultiBinding StringFormat="{}{0} - v{1}">
      <Binding Path="AppTitle" />
      <Binding Path="AppVersion" />
    </MultiBinding>
  </Window.Title>

这不会在MainWindow 中显示任何标题。

但是在 MainWindow 的 CodeBehind 中:

public MainWindow() : base()
{
  InitializeComponent();
  DataContext = new MainViewModel(new MyEntities());
  System.Windows.Forms.MessageBox.Show(string.Format("App: {0}, v: {1}",
      AppTitle, AppVersion));
}

我收到一个显示正确信息的消息框:

注意:多重绑定语法有效。在尝试从 BaseWindow 访问它之前,我尝试使用 Window 的 ViewModel 中的属性进行此操作。

基本原理是我想在应用程序中其他窗口的标题中显示子系统名称,例如“我的应用程序 - 小部件系统”,在子系统 VM 中只有子系统的名称。

【问题讨论】:

  • 'Fails' 意味着根本没有标题。没有错误。没想到在 MessageBox 工作时寻找绑定错误。将仔细检查。
  • 你必须在属性setter和getter中使用SetValue和GetValue。否则 .NET 属性不与 DependencyProperty 耦合
  • 已更改,结果相同。在使用 BaseWindow 之前,我已尝试使用 typeof(Window)typeof(MainWindow)。他们都没有工作。看起来我需要一个 BaseViewModel。
  • 引号使用错误:使用&lt;Binding Path="AppTitle", RelativeSource="{RelativeSource Mode=Self}" /&gt;
  • @Clemens AppVer 在代码中得到更正。我会在问题中解决它。我很抱歉,但我想我已经把它变成了一个红鲱鱼。 AppTitle 应该仍然可以工作,如果这是问题所在,不是吗?

标签: c# wpf inheritance


【解决方案1】:

XAML 代码中MainWindow 的绑定指的是此窗口的 DataContext。设置为MainWindowModel。因此框架尝试绑定到MainWindowModel 对象的属性AppTitle。但是您的属性是在窗口类中定义的。

所以你必须明白:绑定不绑定到自己类的属性,而是绑定到你设置的 DataContext 的属性。

您可以在窗口构造函数中设置DataContext=this。这会显示标题,但当然会与您的意图相矛盾。

更好地使用 RelativeSource 绑定:

<MultiBinding StringFormat="{}{0} - v{1}">
    <Binding Path="AppTitle" RelativeSource="{RelativeSource Self}"/>
    <Binding Path="AppVersion" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>

请注意,这种方式不会反映构造函数调用后 AppTitle 和 AppVersion 的更改。因此,您应该将这些属性设置器设为私有(或受保护)。

如果您想在之后更改属性,则必须使用依赖属性或实现 INotifyPropertyChanged。

【讨论】:

  • 我正在尝试 DependencyProperty 的想法,但它仍然没有显示。是 RelativeSource Self,还是应该是 AncestorType?
  • 不,如果它是窗口类的 DependencyProperty,则应该可以使用 RelativeSource Self 来引用它。你在窗口类中实现了所有DependencyProperty.Register 的东西吗?
  • 刚刚找到它的明确代码:https://stackoverflow.com/questions/9603803/wpf-bind-title-of-window-to-property。查看 Louis Kottmann 的答案
  • 我想我已经正确注册了。编辑了问题。
  • @Clemens:这是有道理的,因为它作为 DependencyProperty 工作,而不是作为简单属性工作。如果它是对 DataContext 的绑定,你是对的
【解决方案2】:

您的属性是在您的视图中定义的,而不是您的视图模型,它是您用于绑定的 DataContext。

要么将属性移动到(基本)视图模型,要么您可以将它们设为静态并在绑定中通过{x:Static viewNamespace:BaseWindow.AppVersion} 引用它们。最干净的选择是第一个,因为视图不应包含数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    相关资源
    最近更新 更多