INotifyPropertyChanged,没有 UI 更新

发布于 2024-12-07 17:08:54 字数 1840 浏览 7 评论 0原文

我在网上寻找答案,但似乎无法让它发挥作用。这是我所拥有的:

public class UIValues : INotifyPropertyChanged
    {
        private double zoomValue = 1;

        private static readonly UIValues instance = new UIValues();

        public event PropertyChangedEventHandler PropertyChanged;

        internal static UIValues Instance { get { return instance; } }

        internal double ZoomValue
        {
            get { return zoomValue; }
            set
            {
                if (this.zoomValue == value)
                    return;

                this.zoomValue = value;
                this.OnPropertyChanged(new PropertyChangedEventArgs("ZoomValue"));
            }
        }

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, e);
        }
    }

然后我有这个:

<UserControl>
    <UserControl.DataContext>
            <local:UIValues x:Name="uiValues"/>
        </UserControl.DataContext>

.
.
.

                <Viewbox x:Name="vbViewBox" RenderTransformOrigin="0.5,0.5">
                    <local:ImageControl x:Name="imgControl" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                    <Viewbox.RenderTransform>
                            <TransformGroup>
                                    <CompositeTransform x:Name="trCompositeTransform" ScaleX="{Binding ZoomValue}" ScaleY="{Binding ZoomValue}" Rotation="0" SkewX="0" SkewY="0"/>
                            </TransformGroup>
                    </Viewbox.RenderTransform>
                </Viewbox>
</UserControl>

所以基本上,每当我从代码隐藏的 UIValues 类中对 ZoomValue 进行更改时,UI 都不会更新。

有人知道为什么吗?

谢谢!

I looked around the web for an answer, but can't seem to get this to work. Here is what I have:

public class UIValues : INotifyPropertyChanged
    {
        private double zoomValue = 1;

        private static readonly UIValues instance = new UIValues();

        public event PropertyChangedEventHandler PropertyChanged;

        internal static UIValues Instance { get { return instance; } }

        internal double ZoomValue
        {
            get { return zoomValue; }
            set
            {
                if (this.zoomValue == value)
                    return;

                this.zoomValue = value;
                this.OnPropertyChanged(new PropertyChangedEventArgs("ZoomValue"));
            }
        }

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, e);
        }
    }

and then I have this:

<UserControl>
    <UserControl.DataContext>
            <local:UIValues x:Name="uiValues"/>
        </UserControl.DataContext>

.
.
.

                <Viewbox x:Name="vbViewBox" RenderTransformOrigin="0.5,0.5">
                    <local:ImageControl x:Name="imgControl" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                    <Viewbox.RenderTransform>
                            <TransformGroup>
                                    <CompositeTransform x:Name="trCompositeTransform" ScaleX="{Binding ZoomValue}" ScaleY="{Binding ZoomValue}" Rotation="0" SkewX="0" SkewY="0"/>
                            </TransformGroup>
                    </Viewbox.RenderTransform>
                </Viewbox>
</UserControl>

So basically, whenever I make a change to the ZoomValue from the UIValues class from code-behind, the UI is not updated.

Anyone know why?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

牛↙奶布丁 2024-12-14 17:08:54

看看发布的代码,我猜测您有类似的东西来更改缩放值。

  UIValues.Instance.ZoomValue = x;

问题是这个 xaml:-

  <local:UIValues x:Name="uiValues"/> 

构造了一个独立的 UIValues 实例,它与静态 Instance 属性返回的实例不同。因此,您将更改没有任何对象监听的对象的值。

编辑

此外,ZoomLevel 是内部,因为它与绑定一起使用,因此必须是公共的。

解决方案是使用 IApplicationService 并通过 App.xaml 执行操作。

将您的类更改为:

public class UIValues : INotifyPropertyChanged,  IApplicationService
{
    private double zoomValue = 1;

    public event PropertyChangedEventHandler PropertyChanged;

    internal static UIValues Instance { get; private set; }

    public double ZoomValue
    {
        get { return zoomValue; }
        set
        {
            if (zoomValue == value)
                return;

            zoomValue = value;
            this.OnPropertyChanged(new PropertyChangedEventArgs("ZoomValue"));
        }
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, e);
    }

    void IApplicationService.StartService(ApplicationServiceContext context)
    {
        Instance = this;
        Application.Current.Resources.Add("UIValues", Instance);
    }

    void IApplicationService.StopService() { }
}

UIValues 的实例添加到 App.Xaml:-

<Application.ApplicationLifetimeObjects>
    <local:UIValues />
</Application.ApplicationLifetimeObjects>

然后像这样设置用户控件 DataContext:-

<UserControl ... DataContext="{StaticResource UIValues}"> 

这就是说这是浪费 DataContext 您可能需要将其绑定到实际数据。您可以直接在绑定上指定 Source:-

 <CompositeTransform ScaleX="{Binding ZoomValue, Source={StaticResource UIValues}}" ScaleY="{Binding ZoomValue, Source={StaticResource UIValues}}" Rotation="0" SkewX="0" SkewY="0"/>

Looking at the posted code I'll have a guess that you have something like this to change the Zoom Value.

  UIValues.Instance.ZoomValue = x;

The problem is this xaml:-

  <local:UIValues x:Name="uiValues"/> 

constructs an independent instance of UIValues that is not the same instance returned by your static Instance property. Hence you will be changing a value on a object that nothing is listening to.

Edit

Also ZoomLevel is internal, for it work with binding is must be public.

The solution is to use IApplicationService and do things through App.xaml.

Change you class to:

public class UIValues : INotifyPropertyChanged,  IApplicationService
{
    private double zoomValue = 1;

    public event PropertyChangedEventHandler PropertyChanged;

    internal static UIValues Instance { get; private set; }

    public double ZoomValue
    {
        get { return zoomValue; }
        set
        {
            if (zoomValue == value)
                return;

            zoomValue = value;
            this.OnPropertyChanged(new PropertyChangedEventArgs("ZoomValue"));
        }
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, e);
    }

    void IApplicationService.StartService(ApplicationServiceContext context)
    {
        Instance = this;
        Application.Current.Resources.Add("UIValues", Instance);
    }

    void IApplicationService.StopService() { }
}

Add the instance of UIValues to App.Xaml:-

<Application.ApplicationLifetimeObjects>
    <local:UIValues />
</Application.ApplicationLifetimeObjects>

Then set the user control DataContext like this:-

<UserControl ... DataContext="{StaticResource UIValues}"> 

That said this is waste of the DataContext which you may need to bind to real data. You can specify the Source directly on the bindings instead:-

 <CompositeTransform ScaleX="{Binding ZoomValue, Source={StaticResource UIValues}}" ScaleY="{Binding ZoomValue, Source={StaticResource UIValues}}" Rotation="0" SkewX="0" SkewY="0"/>
太傻旳人生 2024-12-14 17:08:54

将 ZoomValue 属性的访问修饰符更改为 public,一切都会正常工作。

Change access modifier for ZoomValue property to public and everything will work fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文