【问题标题】:How to set a static class to Data Context?如何将静态类设置为数据上下文?
【发布时间】:2024-04-18 14:05:02
【问题描述】:

我有一个包含 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 中,我将 common:Config 类用作 DataContext,它是一个“普通”类,但我想改用以下类:

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);
    }
}

是一个静态类,好像绑定不了UI。

我能做什么?我必须在标签的绑定中放入什么?

【问题讨论】:

  • DataContext 是Object 类型的属性。您无法为其分配静态类,因为您无法从静态类创建对象实例。您可以分配一个对象(任何类型)。这是基本的 C# 东西......所以,要么不要使类成为静态的,或者,如果这不可能,创建另一个可实例化(!)类,其属性只是访问静态类会话的静态属性。然后创建另一个类的对象实例并将其分配给 DataContext。
  • 是否可以使用静态类来进行数据绑定??
  • 如果您的意思是绑定静态属性,那么答案是:是的,您可以。但是,如果您需要为静态属性实现属性更改通知,请注意这些通知与 INotifyPropertyChanged 实现不同。有关详细信息,请参见此处:msdn.microsoft.com/en-us/library/…

标签: c# wpf data-binding static datacontext


【解决方案1】:

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

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

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

...local 映射到 Session 类的 CLR 命名空间。

【讨论】:

    【解决方案2】:

    您有 2 个解决方案:

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

    2) 将Sesion 设为singleton。这是一个更好的解决方案,因为您可以更好地控制Sesion 的生命周期。此外,您可以使用 Dependency Injection 和其他仅适用于类实例(例如 DataContext 属性)而非静态类的有用模式。

    单例代码sn-p:

    public class Sesion
    {
        static Sesion()
        {
            Instance = new Sesion();
        }
    
        public static Sesion Instance { get; }
    
        private Sesion() { }
    
        public int IdSesion { get; set; }
        //other properties...
    }
    

    然后你可以在MetroWindow.xaml.cs中绑定DataContext

    public partial class MetroWindow : Window
    {
        public MetroWindow()
        {
            InitializeComponents();
    
            DataContext = Sesion.Instance;
        }
    }
    

    另请注意,Binding 仅适用于源属性,不适用于公共字段或方法或其他任何内容。而且,如果你需要监听Sesion类的变化,你需要使Sesion实现INotifyPropertyChanged接口。

    【讨论】:

      【解决方案3】:

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

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

      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>
      

      【讨论】:

        最近更新 更多