使用 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.
备注
- 错误似乎是由于下面显示的
ResourceDictionary.xaml
文件中的 <local:Person x:Key="prs"/>
引用引起的。当“Person.xaml.csclass is instantiated in a button click event defined in
ResourceDictionary.xaml.cs”文件如下所示时,错误发生在 Persona.xaml.cs
文件的第 InitializeComponent();
行。
- 如果我在
App.xaml
文件中引用 <local:Person x:Key="prs"/>
,则会发生完全相同的错误。
- 但是,当我不使用
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.xaml
在 MainWindow
中被引用(而不是在 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 的另一个实例。无论如何都没有使用该资源。
在我的 WPF
项目中,我使用 WindowChrome 来自定义我的 Mainwindow
。当我尝试将 Person.xaml.cs
的 属性 LastName
绑定到 Person.Xaml
文件的 class 代码隐藏时,出现以下错误:
Exception: Cannot find resource named 'prs'. Resource names are case sensitive.
备注
- 错误似乎是由于下面显示的
ResourceDictionary.xaml
文件中的<local:Person x:Key="prs"/>
引用引起的。当“Person.xaml.csclass is instantiated in a button click event defined in
ResourceDictionary.xaml.cs”文件如下所示时,错误发生在Persona.xaml.cs
文件的第InitializeComponent();
行。 - 如果我在
App.xaml
文件中引用<local:Person x:Key="prs"/>
,则会发生完全相同的错误。 - 但是,当我不使用
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.xaml
在 MainWindow
中被引用(而不是在 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 的另一个实例。无论如何都没有使用该资源。