Xaml绑定不更新(一切看起来都应该工作)[duplicate]

2ekbmq32  于 2022-12-07  发布在  其他
关注(0)|答案(2)|浏览(123)

此问题在此处已有答案

Notify binding for static properties in static classes(1个答案)
5个月前关闭。
我已经在一个独特的项目上工作了一段时间,最近我写了一个自定义的“绑定系统”(对于外部代码)这工作得很好,但是今天我需要得到一些MVVM样式的绑定才能工作(对于内部用户界面)。经过一整天的谷歌搜索和尝试不同的东西,我仍然没有一个答案或工作代码。我几乎在一个点上,我只是添加“正常”绑定到我现有的绑定系统,并结束了一天。
我的问题是...
我尝试从一个ViewModel类到一个UI元素进行单向绑定。但是我必须遵守一些“规则(就像所有(public)属性必须在静态类别中)。在设计阶段,一切都正常运作而且VS可以解析系结(如果datacontext是在xaml中设置的,而不是在cs中设置的)。绑定甚至*在启动时*更新一次为其默认值,但不会在属性源更改时

TLDR;请阅读粗体文本:)
代码:
**[公共静态类]**此处的属性由外部代码在运行时设置

public static class StaticClass
{
    public static string ExampleProperty
    {
        get
        {
            return ViewModel.Instance.ExampleProperty;
        }
        set
        {
            if (ViewModel.Instance.ExampleProperty != value) ViewModel.Instance.ExampleProperty = value;
        }
    }
}

**[ViewModel]**一个单元集类,它为上述类中的静态属性保存非静态支持字段,并实现INotifyPropertyChanged

internal class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private static ViewModel _instance = null;
    internal static ViewModel Instance
    {
        get
        {
            if (_instance is null) _instance = new();
            return _instance;
        }
    }

    private static string _exampleProperty { get; set; } = "Pls work"; 

    public string ExampleProperty
    {
        get
        {
            return _exampleProperty;
        }
        set
        {
            _exampleProperty = value;
            OnPropertyChanged();
        }
    }

    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        if (propertyName is not null) PropertyChanged?.Invoke(null, new(propertyName));
    }
}

[Xaml范例系结]

<Button Content="{Binding ExampleProperty, UpdateSourceTrigger=PropertyChanged}" Click="Button_Click"/>

**[MainWindow.cs]**显然是一个测试项目,因此这只是将ExampleProperty更改为Button.Click事件上的随机数

public partial class MainWindow : Window
{
    Random random = new();

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = ViewModel.Instance;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Button btn = (Button)sender;
        StaticClass.ExampleProperty = random.Next(0, 69).ToString();
    }
}

那我做错了什么?任何帮助都是非常感谢的。

slsn1g29

slsn1g291#

表达式

DataContext = new ViewModel();

将ViewModel类的一个不同示例分配给DataContext,而不是从ViewModel.Instance返回的示例,因此

StaticClass.ExampleProperty = random.Next(0, 69).ToString();

不会影响DataContext。您应该已经指派

DataContext = ViewModel.Instance;

然而,您的ViewModel类没有正确实现单例模式-它必须避免创建多个示例,例如通过声明私有构造函数。
视图完全不需要使用视图模型的singleton方面。要访问当前视图模型示例,请将DataContext转换为:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Button btn = (Button)sender;
    ViewModel vm = (ViewModel)btn.DataContext;
    vm.ExampleProperty = random.Next(0, 69).ToString();
}
cbwuti44

cbwuti442#

感谢对问题的评论:

Also be aware that it is possible to bind directly to static properties of a static class, even with change notification, thus eliminating the need for a singleton. See e.g. here: stackoverflow.com/a/41823852/1136211

(and答案)我已经成功地使用了静态和非静态绑定(最后...)。

用于将UI绑定到静态类

    • 静态类:**
public static class StaticClass
{
    public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged;

    #region Properties

    public static string _exampleProperty = "Default value";
    public static string ExampleProperty
    {
        get
        {
            return _exampleProperty;
        }
        set
        {
            if (_exampleProperty != value)
            {
                _exampleProperty = value;
                OnStaticPropertyChanged();
            }
        }
    }

    #endregion

    private static void OnStaticPropertyChanged([CallerMemberName]string propertyName = null)
    {
        StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(propertyName));
    }
}
    • 如何绑定到UI:**
<TextBlock Text="{Binding Path=(local:StaticClass.ExampleProperty)}"/>
    • 如何设置属性:**
StaticClass.ExampleProperty = "New value that automatically updates the UI :)";

用于将UI绑定到非静态类

使用另一个答案中的代码。

相关问题