我能否将DataContext设置为静态类?

9

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

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

我应该如何设置控件的DataContext等于该类?

代码:

/// <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:

<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>
3个回答

13

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

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

以下是示例:

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

如果您只想绑定每个值,最好忽略数据上下文,使用{x:Static binding。例如,以下代码将绑定程序名称的静态属性:

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

我认为这正是我正在寻找的。 - Will

8

从原始问题的版本中:

我将其声明为静态,因为我只需要一个类的全局访问实例。

这并不是静态类。你永远无法拥有任何静态类的实例。

虽然你现在已经修改了问题,以指涉不存在任何实例,但单个实例确实可能是更好的选择,因为通过数据上下文进行绑定更适合实例。

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

你可以很容易地制作一个单例模式:

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
}

需要注意的是,还有其他各种实现选项 - 请参见我的相关页面以获取更多示例。

然后,您需要将DataContext设置为引用单例实例。(我假设在WPF中很容易做到这一点 - 因为我已经很久没有这样做了。)

如果没有这个单例实例,您唯一可能设置DataContext的东西就是类型本身 - 除非WPF特别知道在将上下文设置为类型时获取被引用类型的静态成员,否则我看不出它能起作用。


好的,没错,我使用了不正确的术语。我根本不想要类的任何实例,我只是想要一个结构,通过它可以访问这些信息。已编辑... - Will
@Will:那么你就不能将DataContext属性设置为那个。我怀疑你真正想要的是一个单一实例 - 查看我的编辑以了解如何实现。 - Jon Skeet
那么,如果我按照这种方式实现它,我希望类本身没有静态属性,对吗? - Will
我得到了这个错误: 类型<class>不包含任何可访问的构造函数。 - Will
让我们在聊天中继续这个讨论 - Will
显示剩余2条评论

0

这个语法也适用于绑定到静态属性,而不会生成错误(我不知道为什么):

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接