【问题标题】:Basic Databinding in WPFWPF 中的基本数据绑定
【发布时间】:2012-11-08 20:51:45
【问题描述】:

我目前正在编写一个用于绘制类图的程序,并且我正在使用 MVVM 模式。我的类在用户界面中的宽度和高度设置为自动,因为我让包含的元素定义大小。

问题是我需要模型中的宽度和高度来进行一些计算,所以我需要反向绑定或其他东西来更新模型中的属性,这我不太了解。我该怎么做?

我试过了,但没有用:

XAML:

Width="{Binding Width, Mode=OneWayToSource}" Height="{Binding Height,
Mode=OneWayToSource}">

C#

private int width;
    public int Width {
        get { return width; }
        set {
            width = value;
        }
    }
    private int height;
    public int Height {
        get { return height; }
        set {
            height = value;
        }
    }

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    当您调整 XAML 指向的任何元素的大小时,您所拥有的应该正确更新您的宽度和高度成员变量。

    如果您还想更新代码中的值并将其反映在 XAML 元素中,则需要 INotifyPropertyChanged 和 TwoWay 绑定。您也可以使用依赖属性,但您可能不想在 ViewModel 代码中这样做。

    编辑:根据我下面的评论,您似乎想绑定到 ActualWidth 和 ActualHeight 属性。 MS Silverlight 文档指出:

    出于 ElementName 绑定的目的,ActualWidth 在更改时不会发布更新(由于其异步和运行时计算性质)。不要尝试将 ActualWidth 用作 ElementName 绑定的绑定源。如果您有需要基于 ActualWidth 进行更新的场景,请使用 SizeChanged 处理程序。

    .NET Framework 4.5 文档没有说明同样的警告,但它似乎暗示了 ReadOnly DP。我还看到了使用 XAML 中的触发器在线解决此问题的方法。请参阅接受的答案here 之后的讨论。该讨论表明 MS 无意使用 ReadOnly DP 解决此问题。

    【讨论】:

    • 非常感谢您引导我朝着正确的方向前进。我找到了解决方案here,现在终于可以使用了。
    • 很好,您找到了解决方案,我也有兴趣阅读它,因此感谢您将链接作为评论发布。抱歉,我一开始就无法更具体地回答!
    【解决方案2】:

    你可以试试

    ActualWidth="{Binding Width, Mode=OneWayToSource}" ActualHeight="{Binding Height,
    Mode=OneWayToSource}">
    

    但此代码可能并非每次都有效,因为在呈现 UI 之前,实际的宽度和高度不可用。

    或者您可以在 VM 中创建依赖属性,并使用 Mode=OneWay 将其与宽度和高度绑定。但是当您使用 MVVM 时,您的框架应该支持这一点。

    【讨论】:

      【解决方案3】:

      已编辑:

      您可能需要做 3 件事。

      1. 您的类(定义了 Width 和 Height 属性的模型或视图模型)需要实现 INotifyPropertyChanged 接口。

      2. 您还需要两种方式绑定,因为您想从代码中设置宽度/高度以及从用户那里获取它。

      3. 需要绑定ActualWidth和ActualHeight - What is the difference between Width and ActualWidth in WPF?

      有关 INotifyPropertyChanged 的​​更多信息 - http://msdn.microsoft.com/en-us/library/ms743695.aspx

      【讨论】:

      • 它已经实现了 INotifyPropertyChanged。而且我不需要从代码中设置宽度/高度,这些设置为自动,这样当包含的元素增长时,容器也会增长。我只需要我的模型在视图的自动宽度和自动高度发生变化时更改其属性。
      • 您的示例代码没有实现 INotifyPropertyChanged。在我看来,您需要绑定到 ActualWidth 和 ActualHeight 而不是 Width 和 Height。
      • 我认为你是对的,但由于 ActualWidth 和 ActualHeight 是只读的,我无法使用 ActualWidth="{Binding Width}" Mode="OneWayToSource" 语法绑定到它。
      • 从进一步的研究来看,这似乎是设计使然。我已经用几个链接更新了我的答案。
      【解决方案4】:

      确保您的视图模型设置为视图的 DataContext。您需要在视图模型中实现 INotifyPropertyChanged。然后,将您的属性更新为如下所示:

          public int Width 
          {
              get { return width; }
              set 
                {
                  if(width != value)
                    {
                       width = value;
                       NotifyPropertyChanged();
                    }
                }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-30
        • 1970-01-01
        • 2013-02-24
        • 2010-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-20
        相关资源
        最近更新 更多