如何将静态 class 设置为数据上下文?

How to set a static class to Data Context?

我有一个包含 4 个项目的解决方案。

在 UI 项目中,我有这个 XAML:

<Controls:MetroWindow x:Class="QuaverUI.Inicio.Principal"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:behaviours="clr-namespace:MahApps.Metro.Behaviours;assembly=MahApps.Metro"
    xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
    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:QuaverUI.Inicio"    
    xmlns:common="clr-namespace:Common;assembly=Common"
    mc:Ignorable="d"
    BorderThickness="0" 
    GlowBrush="Black"
    Title="Quaver" Height="700" Width="1250" 
    WindowStartupLocation="CenterScreen"Closing="MetroWindow_Closing">

    <Window.DataContext>
        <common:Config/>
    </Window.DataContext>

</Controls:MetroWindow>

如你所见,在XAML中我使用classcommon:Config作为DataContext,它是一个"normal"class,但我想改用下面的:

public static class Sesion
{
    public static int idSesion;
    public static string usuarioSesion;
    public static string rolSesion;
    public static string nombres;
    public static string primerApellido;
    public static string segundoApellido;

    public static string GetNombreCompleto()
    {
        return string.Format("{0} {1} {2}",
            nombres, primerApellido, segundoApellido);
    }
}

它是一个静态 class,我似乎无法将它绑定到 UI。

我能做什么?我必须在标签的绑定中添加什么?

您有 2 个解决方案:

1) 保持 Sesion 静态并像 @elgonzo 建议的那样实施 StaticPropertyChanged

2) 使 Sesion 成为 singleton. This is a better solution because you have more control on the Sesion lifetime. Also, you can use Dependency Injection 和其他仅适用于 class 实例的有用模式(例如 DataContext 属性),而不是静态 classes.

单例代码片段:

public class Sesion
{
    static Sesion()
    {
        Instance = new Sesion();
    }

    public static Sesion Instance { get; }

    private Sesion() { }

    public int IdSesion { get; set; }
    //other properties...
}

然后您可以将 DataContext 绑定到 MetroWindow.xaml.cs:

public partial class MetroWindow : Window
{
    public MetroWindow()
    {
        InitializeComponents();

        DataContext = Sesion.Instance;
    }
}

另请注意,a Binding 仅适用于源 PROPERTIES,不适用于 public 字段或方法等。而且,如果你需要监听 Sesion class 的变化,你需要让 Sesion 实现 INotifyPropertyChanged 接口。

由于您无法创建静态 class 的实例,因此将 DataContext 设置为您的 Sesion class 或类型是没有意义的。

但是您可以像这样将每个元素绑定到该类型的静态属性:

<TextBlock Text="{x:Static local:Sesion.rolSesion}" />

...其中 local 映射到 Sesion class.

的 CLR 命名空间

我知道这是两年前的事情了,但还有第三种解决方案如下:

a) 创建一个单例 class,例如

public class DataManager
{
    private static DataManager __instance = null;
    private static readonly object _padlock = new object();

    public static DataManager Instance
    {
        get
        {
            if (__instance == null)
            {
                lock (_padlock)
                {
                    if (__instance == null)
                    {
                        __instance = new DataManager();
                    }
                }
            }
            return __instance;
        }
    }

    private DataManager()
    { }

    // your stuff as needed ...
}

b) 在 xaml 中声明 DataManager 所在的名称空间,例如

xmlns:data="clr-namespace:MyWonderfulApp.Namespace"

c) 在xaml 中声明数据上下文

<Window.DataContext>
    <ObjectDataProvider ObjectInstance="{x:Static data:DataManager.Instance"/>
</Window.DataContext>