【问题标题】:WPF binding issues while using MVVM使用 MVVM 时出现 WPF 绑定问题
【发布时间】:2012-08-19 04:43:06
【问题描述】:

是我第一个问题的时间了 :)

我有以下几点:

public class BuilderViewModel : INotifyPropertyChanged
{
    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion

    private double _contentScale = 1.0;

    public double ContentScale
    {
        get { return _contentScale; }
        set
        {
            _contentScale = value;
            NotifyPropertyChanged("ContentScale");
        }
    }

    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    } 

    #region Commands

    bool CanZoomIn() { return true; }
    void ZoomInExecute()
    {
        ContentScale += 1.0;
    }

    public ICommand ZoomIn { get { return new RelayCommand(ZoomInExecute, CanZoomIn); } }

    #endregion
}

以及对应的视图:

<UserControl x:Class="PS_IDE.FormBuilder.View.Builder"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:PS_IDE.FormBuilder.ViewModel">
    <UserControl.DataContext>
        <local:BuilderViewModel />
    </UserControl.DataContext>

    <TextBox Text="{Binding ContentScale}" Width="100" />

</UserControl>

我正在尝试让 BuilderViewModel 中的 ZoomIn 命令更新其视图中的文本框值。该命令是从另一个用户控件 UIBuilder 触发的,其中包括 Builder。如果我从 UIBuilder 调试并触发命令,我可以看到它正确更新 ContentScale。

但是,我的文本框值没有更新(它只显示“1”,即 ContentScale 的初始值)。

我知道我错过了一些东西,希望有人能指出我正确的方向。

编辑:添加了触发命令的控件

<UserControl x:Class="PS_IDE.FormBuilder.UIBuilder"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:PS_IDE.FormBuilder"
         xmlns:ViewModel="clr-namespace:PS_IDE.FormBuilder.ViewModel"
         xmlns:View="clr-namespace:PS_IDE.FormBuilder.View" mc:Ignorable="d">  
    <UserControl.DataContext>
        <ViewModel:BuilderViewModel />
    </UserControl.DataContext>
    <DockPanel LastChildFill="True">

        ....

        <ToolBarTray DockPanel.Dock="Bottom" HorizontalAlignment="Right">
            <ToolBar>
                <Button Height="24" Width="24" ToolTip="Zoom In" Command="{Binding ZoomIn}">
                    <Image Source="Images/ZoomIn.png" Height="16"/>
                </Button>

                ....

            </ToolBar>
       </ToolBarTray>
       <View:Builder x:Name="builder" />
    </DockPanel>
</UserControl>

【问题讨论】:

  • 你能告诉我们触发ZoomIn命令的控件吗?
  • 我把它加到原帖的末尾了:)
  • 只是为了它,如果你这样做 ContentScale = ContenScale + 1.0; 它是否有效?而不是 ContentScale += 1.0; ?您确定您使用相同的 BuilderViewModel 实例作为两个视图的数据上下文吗?
  • 不,同样的问题。我可以在调试器中看到它正在更新,但绑定仍未更新。
  • 您在输出窗口中是否收到任何类型的绑定错误消息?

标签: c# .net data-binding mvvm command


【解决方案1】:

使用设置在两个视图中

<UserControl.DataContext>
    <local:BuilderViewModel />
</UserControl.DataContext>

您基本上是在创建两个视图模型,每个视图一个。因此,当您的命令更新属性时,它会在其中一个视图模型上执行此操作,但您的文本框绑定到不同的视图模型。

要解决它删除 DataContext 设置从Builder.xaml

此外,您需要将 DataContext 传递给您的 Builder 控件(这两个视图将共享相同的视图模型)。

所以修改你的 UIBuilder.xaml:

<View:Builder x:Name="builder" DataContext="{Binding}" />

【讨论】:

  • 啊,好吧,这完全有道理。我知道我错过了一些东西。我的所有问题都已解决,非常感谢您的帮助!
【解决方案2】:

在绑定中使用 Mode TwoWay

 Text ="{Binding ElementName=BuilderViewModel,
         Path=ContentScale,
         Mode=TwoWay,
         UpdateSourceTrigger=PropertyChanged}"

注意:使用 observable 集合发送通知

【讨论】:

  • Mode TwoWay 是 WPF 中 TextBox.Text 的默认设置,无论如何,当视图模型中的更改未反映在视图中时,OP 在另一个方向上存在问题。
  • 我已经尝试过 TwoWay。我只需要一种方式,即当 ViewModel 更新时,View 会反映这一点。
  • 添加 observable 集合以便向视图发送通知
猜你喜欢
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 2011-04-07
  • 2010-12-15
相关资源
最近更新 更多