如何将静态 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>
我有一个包含 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.
我知道这是两年前的事情了,但还有第三种解决方案如下:
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>