使用 ResourceDictionary 时无法使用 XAML 绑定到 class 实例的 属性

Unable to use XAML to bind to a property of a class instance when using ResourceDictionary

在我的 WPF 项目中,我使用 WindowChrome 来自定义我的 Mainwindow。当我尝试将 Person.xaml.cs 的 属性 LastName 绑定到 Person.Xaml 文件的 class 代码隐藏时,出现以下错误:

Exception: Cannot find resource named 'prs'. Resource names are case sensitive.

备注

  1. 错误似乎是由于下面显示的 ResourceDictionary.xaml 文件中的 <local:Person x:Key="prs"/> 引用引起的。当“Person.xaml.csclass is instantiated in a button click event defined inResourceDictionary.xaml.cs”文件如下所示时,错误发生在 Persona.xaml.cs 文件的第 InitializeComponent(); 行。
  2. 如果我在 App.xaml 文件中引用 <local:Person x:Key="prs"/>,则会发生完全相同的错误。
  3. 但是,当我不使用 ResourceDictionary 自定义 MainwWindow 而是在中引用 <local:Person x:Key="prs"/> 时,错误确实 NOT 发生App.xaml 文件。

问题:我可能做错了什么,我们如何在仍然使用 ResourceDictionary 自定义 MainWindow 的同时解决问题?

Person.xaml:

<Window x:Class="MyProject.Commands.Person"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       xmlns:local="clr-namespace:MyProject">

    <Grid>
        <Label>Last Name:</Label>
        <TextBox Name="txtLastName">
            <TextBox.Text>
                <Binding Path="LastName" Source="{StaticResource prs}" UpdateSourceTrigger="PropertyChanged">
                </Binding>
            </TextBox.Text>
        </TextBox>
 </Grid>
</Window

Person.xaml.cs

namespace MyProject.Commands
{
  public partial class Person: Window
  {
      public Person()
      {
          InitializeComponent(); //the above ERROR occurs here
      }

      public string LastName
      {
          get { return txtLastName.Text; }
      }
  }
}

ResourceDictionary.xaml:第一行

中引用了数据源<local:Person x:Key="pers"/>
<ResourceDictionary x:Class="MyProject.WindowStyle"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyProject.Commands">

<local:Person x:Key="pers"/>

    <Style x:Key="CustomWindowStyle" TargetType="{x:Type Window}">
        <Setter Property="WindowChrome.WindowChrome">
            <Setter.Value>
                <WindowChrome CaptionHeight="30"
                              CornerRadius="4"
                              GlassFrameThickness="0"
                              NonClientFrameEdges="None"
                              ResizeBorderThickness="5"
                              UseAeroCaptionButtons="False" />
            </Setter.Value>
        </Setter>
        <Setter Property="BorderBrush" Value="Black" />
        <Setter Property="Background" Value="Gray" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <Grid>
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="5,30,5,5">
                            <AdornerDecorator>
                                <ContentPresenter />
                            </AdornerDecorator>
                        </Border>

                        <DockPanel Height="30"
                                   VerticalAlignment="Top"
                                   LastChildFill="False">

                            <TextBlock Margin="5,0,0,0"
                                       VerticalAlignment="Center"
                                       DockPanel.Dock="Left"
                                       FontSize="16"
                                       Foreground="White"
                                       Text="{TemplateBinding Title}" />

                            <Button x:Name="btnClose"
                                    Width="15"
                                    Margin="5"
                                    Click="CloseClick"
                                    Content="X"
                                    DockPanel.Dock="Right"
                                    WindowChrome.IsHitTestVisibleInChrome="True" />


                            <Button x:Name="btnRestore"
                                    Width="15"
                                    Margin="5"
                                    Click="MaximizeRestoreClick"
                                    Content="#"
                                    DockPanel.Dock="Right"
                                    WindowChrome.IsHitTestVisibleInChrome="True" />

                            <Button x:Name="btnMinimize"
                                    Width="15"
                                    Margin="5"
                                    VerticalContentAlignment="Bottom"
                                    Click="MinimizeClick"
                                    Content="_"
                                    DockPanel.Dock="Right"
                                    WindowChrome.IsHitTestVisibleInChrome="True" />

                            <Button x:Name="btnAddPerson"
                                    Width="15"
                                    Margin="5"
                                    VerticalContentAlignment="Bottom"
                                    Click="btnAddPerson_Click"
                                    Content="_"
                                    DockPanel.Dock="Right"
                                    WindowChrome.IsHitTestVisibleInChrome="True" />

                        </DockPanel>

                    </Grid>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

ResourceDictionary.xaml.cs:

namespace SciDoxViewer
{
    public partial class WindowStyle : ResourceDictionary
    {
        public WindowStyle()
        {
            InitializeComponent();
        }
     
        //Here: click events for other buttons in above ResourceDictionary.xaml file
        ...............
        ...............
        private void btnAddPerson_Click(object sender, RoutedEventArgs e)
        {
                Person person = new Person(); //This line first takes you to `InitializeComponent();` of the constructor of `Person` class where the above error occurs.

                if (person.ShowDialog() == true)
                {
                    .....
                }
        }
  }
}

更新 [日期:2020 年 11 月 5 日]

WindowStyle.xamlMainWindow 中被引用(而不是在 Person.xaml 中),如下所示。 MainWindow.xaml:

<Window x:Class="MyProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyProject"
        mc:Ignorable="d"
        Style="{StaticResource CustomWindowStyle}">
<Grid>
....
</Grid>
</Window>

App.xaml:

<Application x:Class="MyProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:SciDoxViewer.Commands"
             xmlns:main="clr-namespace:MyProject"
             StartupUri="MainWindow.xaml">

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/MyProject;component/WindowStyle.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>       
    </Application.Resources>
</Application>

您应该从资源字典中删除 Person 资源,因为您已经在单击事件处理程序中创建了 Person window 的另一个实例。无论如何都没有使用该资源。