wpf 我可以将 DataContext 设置为静态类吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27880492/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:50:02  来源:igfitidea点击:

Can I set a DataContext to a static class?

c#wpfxamlstaticdatacontext

提问by Will

I've a static class which reads information from the application assembly.

我有一个静态类,它从应用程序程序集中读取信息。

I've declared it static since the class needs no instance declaration and will only ever be read directly from, application-wide. I have a control with several labels that I would like to use to display some of this information.

我已将其声明为静态,因为该类不需要实例声明,并且只能直接从应用程序范围内读取。我有一个带有多个标签的控件,我想用它们来显示其中的一些信息。

How can I go about setting the controls DataContext equal to the class?

如何将控件 DataContext 设置为等于类?

Code:

代码:

/// <summary>
/// Class for Reading Program Information.
/// </summary>
public static class ProgramInfo {
    private static Assembly ProgramAssembly = Assembly.GetEntryAssembly( );

    /// <summary>
    /// Get Program Name
    /// </summary>
    public static string ProgramName {
        get { return ProgramInfo.ProgramAssembly.GetCustomAttribute<AssemblyProductAttribute>( ).Product; }
    }

    /// <summary>
    /// Get Program Build Date
    /// </summary>
    public static DateTime BuildDate {
        get { return File.GetLastWriteTime( ProgramInfo.ProgramAssembly.Location ); }
    }

    /// <summary>
    /// Get Program Version (Major.Minor)
    /// </summary>
    public static string Version {
        get {
            System.Version V = ProgramInfo.ProgramAssembly.GetName( ).Version;
            return V.Major.ToString( ) + '.' + V.Minor.ToString( );
        }
    }

    /// <summary>
    /// Get Program Build (Build.Revision)
    /// </summary>
    public static string Build {
        get {
            System.Version V = ProgramInfo.ProgramAssembly.GetName( ).Version;
            return V.Build.ToString( ) + '.' + V.Revision.ToString( );
        }
    }
}

XAML:

XAML:

<UserControl x:Class="Tools.Controls.ProgramInformation"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:pi="clr-namespace:Tools.Controls">
<UserControl.DataContext>
    <pi:ProgramInfo/>
</UserControl.DataContext>
<!--Other Irrelevant Code-->
</UserControl>

回答by Michael G

You can bind to a static field or property by using the {x:Static}binding syntax.

您可以使用{x:Static}绑定语法绑定到静态字段或属性。

x:Static is used to get static fields and properties. You can set the datacontext to a static field, or property, but not to a static type.

x:Static 用于获取静态字段和属性。您可以将数据上下文设置为静态字段或属性,但不能设置为静态类型。

Example below:

下面的例子:

<DataContext Source="{x:Static prefix:typeName.staticMemberName}" />

It'd be more appropriate for you to ignore the datacontext, and just use a {x:Static binding for each value you wish to bind. For example, below would bind the program name static property:

忽略数据上下文对您来说更合适,只需为您希望绑定的每个值使用 {x:Static 绑定。例如,下面将绑定程序名称静态属性:

<TextBlock Text="{Binding Source={x:Static pi:ProgramInfo.ProgramName}}" /> 

回答by Jon Skeet

From the original version of the question:

从问题的原始版本:

I've declared it static since I will only ever need a single application-wide accessible instance of the class.

我已将其声明为静态,因为我只需要该类的一个应用程序范围的可访问实例。

That's not what a static class is. You can never have anyinstance of a static class.

那不是静态类。您永远不能拥有静态类的任何实例。

Although you've now changed the question to refer to there being noinstances, a single instance really is probably a better idea, as binding via a data context is more geared up for instances.

尽管您现在已将问题更改为没有实例,但单个实例确实可能是一个更好的主意,因为通过数据上下文进行绑定更适合实例。

What you're probably looking for is a singleton- where you cancreate an instance, and most of the members are instance members, but where there's guaranteed to only be a single instance.

您可能正在寻找的是单例- 您可以在其中创建一个实例,并且大多数成员都是实例成员,但保证只有一个实例。

You can make a singleton very easily:

您可以非常轻松地制作单身人士:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    public static Singleton Instance { get { return instance; } }

    // Private constructor to prevent instantiation
    private Singleton() {}

    // Instance members from here onwards
}

There are various other implementation options, mind you - see my page on the topicfor more examples.

请注意,还有各种其他实现选项 -有关更多示例,请参阅我的主题页面

Then you'd set the DataContextto refer to the singleton instance. (I assume that's easy enough in WPF - it's been too long since I've done it.)

然后将 设置DataContext为引用单例实例。(我认为这在 WPF 中已经足够简单了 - 自从我完成它以来已经太久了。)

Without that single instance, the only thing you could potentially set your DataContextto would be the type itself - and unless WPF is set up to specifically know to fetch the static members of the type which is being referenced when the context is set to a type, I can't see it working.

如果没有该单个实例,您唯一可以设置的DataContext可能是类型本身 - 除非 WPF 被设置为明确知道在上下文设置为类型时获取正在引用的类型的静态成员,我看不到它在工作。

回答by BoiseBaked

This syntax also works for databinding to static properties without generating the error (and I have no idea why):

此语法也适用于静态属性的数据绑定,而不会产生错误(我不知道为什么):

DataContext={Binding Path=(prefix:TypeName.StaticPropertyName)}

DataContext={绑定路径=(前缀:TypeName.StaticPropertyName)}