1

我有松散形式的 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 中。

谁能证实这一点,或纠正我的假设?

编辑

我错了。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 中资源字典的支持类)中的值时,我可以更改这些值,但它们仍然没有反映在箭头路径中。

有谁知道如何从代码隐藏中更改这些值?

4

1 回答 1

1

将我的评论转换为答案。

向类添加公共构造函数,MainWindowResource例如:

public MainWindowResource() {
  Debug.WriteLine("Called");
}

看看它被调用了多少次。我的猜测是两个。需要注意的一个稍微棘手的事情是重新定义资源不会导致新对象的创建,直到该资源实际用于子范围。

在您的情况下,您可以从 MainWindow 中删除资源重复定义,因为它在 App.xaml 中声明时(通过ResourceDictionary),它已经可供 MainWindow.xaml 使用,从而使重新定义毫无意义。

于 2013-07-17T16:06:18.447 回答