我的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。
答案 0 :(得分:1)
是的,我很蠢。
我的ViewModel基类在从另一个项目合并时丢失了INotifyPropertyChanged接口。 所以我调用了OnPropertyChanged,但它是我自己的OnPropertyChanged,而不是WPF绑定等待接口的实现。
答案 1 :(得分:0)
我在代码示例中指出了一些内容:
_pacient = App.instance.sessionData.serviceProxy.pacientById(value.Value);
代码始终返回相同的对象实例。INotifyPropertyChanged
界面,在大多数情况下,您提出的属性更改事件如下所示:RaisePropertyChanged('PropertyName');
您正在调用:'OnPropertyChanged();'希望这会有所帮助......