WPF数据绑定:视图不从viewmodel更新

时间:2015-03-27 19:11:07

标签: c# wpf xaml mvvm data-binding

我的WPF应用程序对我来说是一种奇怪的方式 - 一些绑定工作,其他不是。

我有以下情况:

文本框 - 用户提供ID。基于此ID,将加载或创建对象。其他一些属性由来自加载/新对象的值更新。

ID文本框的绑定工作正常。但是,其他两个观点(任何其他观点)都没有。

我的代码示例: XAML:

<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
            <TextBlock Text="ID" FontFamily="Segoe UI Light" />
            <TextBox x:Name="TB_PacientID" Width="100px" HorizontalAlignment="Left" Margin="5,0,0,0" Text="{Binding Path=PacientID}"/>
            <TextBlock x:Name="TBL_NovyPacient" Text="nový pacient" Margin="5,0,0,0" Foreground="Green" FontWeight="Bold" Visibility="{Binding Path=IsNewPacient,UpdateSourceTrigger=PropertyChanged,Converter={StaticResource BTVConverter}}"/>
        </StackPanel>
<WrapPanel x:Name="WP_PacientData" Margin="-2,5,2,5" Visibility="{Binding PacientLoaded,Converter={StaticResource BTVConverter}}">
 ...

视图模型:

public int? PacientID
{
    get
    {
        if (CurrentPacient == null)
            return null;
        return CurrentPacient.id;
    }
    set
    {
        if (value != null)
        {
            _pacient = App.instance.sessionData.serviceProxy.pacientById(value.Value);
            if (_pacient == null)
            {
                CurrentPacient = new Pacient() { id = value.Value };
                IsNewPacient = true;
            }
            else
            {
                CurrentPacient = _pacient;
            }                                                            
            OnPropertyChanged();
            PacientLoaded = true;
        }
    }
}

// ...

public bool IsNewPacient
{
    get{ return _isNewPacient; }
    set
    {
        _isNewPacient = value;
        OnPropertyChanged();
    }
}

//...

public bool PacientLoaded
{
    get{ return _pacientLoaded; }
    set
    {
        _pacientLoaded = value;
        OnPropertyChanged();
    }
}

这个想法: 用户输入ID,加载或创建对象,并显示WrapPanel。如果新创建了对象,则还会显示TextBlock。 转换器工作正常(在另一个窗口中测试)。

当窗口加载时,绑定建立良好(如果我在ctor中设置了一些假值)。更改文本框中的ID时,没有其他任何更新 - 除了ID本身 - 启动setter并在调用OnPropertyChanged后读取新值。

我希望我能错过一些非常简单和愚蠢的事情。

- 编辑: 当前状态: TB_PacientID正在工作(更新),TBL_NovyPacient和WP_PacientData无法正常工作(更新)。 我想要: 所有的视图都从viewmodel(代码属性)进行更新。

-Edit 2 我从头开始创建了一个非常简单的问题示例: 一个窗口 - 两个文本框:

<Window x:Class="bindingTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <TextBox x:Name="TestTextBox" Text="{Binding ID, Mode=TwoWay}"/>
        <TextBox x:Name="SecondTextBox" Text="{Binding IsNew, Mode=TwoWay}"/>

    </StackPanel>
</Window>

代码隐藏:

 namespace bindingTest
 {
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new TestViewModel();
        }
    }
}

viewmodel类:

 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Linq;
 using System.Runtime.CompilerServices;
 using System.Text;
 using System.Threading.Tasks;
 namespace bindingTest
 {
    public abstract class ViewModelBase
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }        
    }

    public class TestViewModel : ViewModelBase
    {
        private bool _attOne;
        private int? id;        

        private bool _isNew;

        public bool IsNew
        {
            get
            {
                return _isNew;
            }
            set
            {
                _isNew = value;
                OnPropertyChanged();
            }
        }

        public int? ID
        {
            get
            {
                return id;
            }
            set
            {
                this.id = value;
                IsNew = true;
                OnPropertyChanged();
            }
        }
    }
}

我只想要 - 如果我更改第一个文本框中的数字,我想自动在第二个文本框中使用True。

2 个答案:

答案 0 :(得分:1)

是的,我很蠢。

我的ViewModel基类在从另一个项目合并时丢失了INotifyPropertyChanged接口。 所以我调用了OnPropertyChanged,但它是我自己的OnPropertyChanged,而不是WPF绑定等待接口的实现。

答案 1 :(得分:0)

我在代码示例中指出了一些内容:

  1. 您应该使用TwoWay绑定来设置ID。
  2. 您确定_pacient = App.instance.sessionData.serviceProxy.pacientById(value.Value);代码始终返回相同的对象实例。
  3. 您是否正确使用INotifyPropertyChanged界面,在大多数情况下,您提出的属性更改事件如下所示:RaisePropertyChanged('PropertyName');您正在调用:'OnPropertyChanged();'
  4. 希望这会有所帮助......