我有松散的MVVM形式,我有一个C#类,包含我的XAML绑定的资源数据。该文件在两个位置引用,MainWindow.xaml文件和App.xaml文件中的应用程序级别。当我在MainWindow代码隐藏中引用它时,似乎只有一个实例,我可以在窗口级别和应用程序级别中看到的那个实例中设置值。有人能确认或纠正这个假设吗? 请参阅下面的编辑
我有一个MainWindow和一个MainWindowResource.cs文件来支持MainWindow的绑定。资源文件看起来像这样(缩短):
public class MainWindowResource : INotifyPropertyChanged
{
#region Data Members
private Color _arrowBorderColor = Colors.Black;
private Color _arrowColor = Colors.Black;
private bool _viewFitYAxis = true;
private string _viewFitYAxisTooltip = "";
#endregion Data Members
#region Properties
public Color ArrowBorderColor
{
get { return _arrowBorderColor; }
set { _arrowBorderColor = value; SetPropertyChanged("ArrowBorderColor"); }
}
public Color ArrowColor
{
get { return _arrowColor; }
set { _arrowColor = value; SetPropertyChanged("ArrowColor"); }
}
public bool ViewFitYAxis
{
get { return _viewFitYAxis; }
set { _viewFitYAxis = value; SetPropertyChanged("ViewFitYAxis"); }
}
public string ViewFitYAxisTooltip
{
get { return _viewFitYAxisTooltip; }
set { _viewFitYAxisTooltip = value; SetPropertyChanged("ViewFitYAxisTooltip"); }
}
#endregion Properties
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void SetPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
#endregion INotifyPropertyChanged implementation
}
我引用了MainWindow XAML中的MainWindowResouce文件:
<Window.Resources>
<c:MainWindowResource x:Key="MainWindowResource"/>
我绑定到MainWindow XAML中MainWindowResource的属性:
<MenuItem x:Name="MenuFitYAxis"
Header="Fit _Y Axis"
IsCheckable="True"
IsChecked="{Binding Source={StaticResource MainWindowResource}, Path=ViewFitYAxis}"
ToolTip="{Binding Source={StaticResource MainWindowResource}, Path=ViewFitYAxisTooltip}"
Click="MenuItem_Click_ViewFitYAxis"/>
我还有一个名为ArrowResources.xaml的资源字典,其中我定义了一些箭头路径。我还希望将一些值外部化到MainWindowResource文件中,使其看起来像这样(缩短):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:UserInterface">
<c:MainWindowResource x:Key="MainWindowResource"/>
<Path x:Key="ArrowCounter"
Stroke="{Binding Source={StaticResource MainWindowResource}, Path=ArrowBorderColor}"
StrokeThickness="1"
Data="M 8,26 L 14,20 L 10,20 A 10,10 0 1 1 30,20 L 34,20 A 14,14 0 1 0 6,20 L 2,20 Z">
<Path.Fill>
<RadialGradientBrush GradientOrigin="0.15,0.2" Center="0.3,0.4">
<GradientStop Color="White"
Offset="0"/>
<GradientStop Color="{Binding Source={StaticResource MainWindowResource}, Path=ArrowColor}"
Offset="1"/>
</RadialGradientBrush>
</Path.Fill>
</Path>
</ResourceDictionary>
资源字典包含在我的App.xaml中,如下所示:
<Application x:Class="UserInterface.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary Source="ArrowResources.xaml"/>
</Application.Resources>
</Application>
在我的MainWindow的代码隐藏中,我获取了对MainWindowResource类的引用,如下所示(缩短):
public partial class MainWindow : Window
{
private MainWindowResource _mainWindowResource = null;
public MainWindow()
{
InitializeComponent();
// get a reference to the binding sources so we can set the properties
_mainWindowResource = (MainWindowResource)this.Resources["MainWindowResource"];
}
}
当我得到这个引用时,似乎只有一个MainWindowResource类的实例,如果我在其中设置了值,那些更改将反映在应用程序级别的MainWindow.xaml和ArrowResources.xaml中。 / p>
任何人都可以证实这一点,或者纠正我的假设吗?
修改
我错了。 ArrowResources.xaml确实看到MainWindowResource.cs中的值,但是当我在MainWindow代码隐藏中获得类的实例并且我更改箭头的值时,箭头路径无法识别更改,因此它不能是同一个实例。
我尝试为箭头创建一个单独的类文件,我在MainWindow的代码隐藏中得到了该类的实例,如下所示:
private MainWindowResource _mainWindowResource = null;
private ArrowResource _arrowResource = null;
. . .
_mainWindowResource = (MainWindowResource)this.Resources["MainWindowResource"];
_arrowResource = (ArrowResource)Application.Current.Resources["ArrowResource"];
但是当我尝试更改ArrowResource类(ArrowResources.xaml中资源字典的支持类)中的值时,我可以更改值,但它们仍未反映在箭头路径中。
有没有人知道如何从代码隐藏中更改这些值?
答案 0 :(得分:1)
将我的评论转换为答案。
将公共构造函数添加到MainWindowResource
类,例如:
public MainWindowResource() {
Debug.WriteLine("Called");
}
并查看它被调用了多少次。我猜是两个。一个稍微棘手的事情是,重新定义资源不会导致新的对象创建,直到所述资源实际用于子范围。
在您的情况下,您可以从MainWindow中删除资源重复定义,就像它在App.xaml中声明的那样(通过ResourceDictionary
),它已经可用于MainWindow.xaml,使重新定义毫无意义。