textBlock未更新(RaisePropertyChanged无法正常工作吗?)

时间:2019-11-02 03:55:28

标签: c# wpf data-binding textblock

我的程序有两个窗口。 MainWindow上TextBox的内容应更改CalcWindow上TextBlock的内容。但是,即使更改了TextBox,TextBlock也不会更改。

我在UISimpleData中添加了“ RaisePropertyChanged”。因此,正确更改了TextBox的内容。但是,它不会更改CalcWindow上的TextBlock。

MainWindow.xaml

<Window x:Class="DoubleToTextBlockBinding.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="DataUpdate" Height="220.276" Width="400">

    <Grid Height="190" Margin="0,0,-0.667,0" VerticalAlignment="Top">
        <Label Content="Target Value" HorizontalAlignment="Right" Margin="0,0,112,142" VerticalAlignment="Bottom" Width="78"/>
        <TextBox Margin="0,0,24,142" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="22" Width="60"
                 Text="{Binding DoubleField, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}">
            <TextBox.Style>
                <Style TargetType="{x:Type TextBox}">
                    <Style.Triggers>
                        <Trigger Property="Validation.HasError" Value="true">
                            <Setter Property="ToolTip" Value="{Binding (Validation.Errors)[0].ErrorContent, 
                                RelativeSource={RelativeSource Self}}"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>
        <TextBlock Text="{Binding DoubleField}" HorizontalAlignment="Right" VerticalAlignment="Bottom" 
                   Margin="0,0,25,115" Height="22" Width="60"/>
        <Button Name="ConfirmButton" Content="Confirm" Margin="85,0,25.666,58" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="ConfirmButton_Click"/>
    </Grid>
</Window>

MainWindow.xaml.cs

using DoubleToTextBlockBinding.ViewModels;
using DoubleToTextBlockBinding.Views;
using System.Windows;

namespace DoubleToTextBlockBinding
{
    public partial class MainWindow : Window
    {
        private UISimpleData _uiData = new UISimpleData();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = _uiData;
        }

        private void ConfirmButton_Click(object sender, RoutedEventArgs e)
        {
            new CalcWindow().Show();
        }
    }
}

App.xaml.cs

using System.Windows;

namespace DoubleToTextBlockBinding
{
    public partial class App : Application
    {
        public App()
        {
            System.Windows.FrameworkCompatibilityPreferences
                       .KeepTextBoxDisplaySynchronizedWithTextProperty = false;
        }
    }
}

Views / CalcWindow.xaml

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModels="clr-namespace:DoubleToTextBlockBinding.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        x:Class="DoubleToTextBlockBinding.Views.CalcWindow"
        Title="Bound Window" Width="400" Height="212">
    <Grid>
        <TextBlock Text="{Binding DoubleField}" x:Name="textBox"  Width="104"
            Margin="148,84,0,0" HorizontalAlignment="Left" VerticalAlignment="Top">
            <TextBlock.DataContext>
                <viewModels:UISimpleData/>
            </TextBlock.DataContext>
        </TextBlock>
    </Grid>
</Window>

Views / CalcWindow.xaml.cs

using System.Windows;
using DoubleToTextBlockBinding.ViewModels;

namespace DoubleToTextBlockBinding.Views
{
    public partial class CalcWindow : Window
    {
        private UISimpleData _uiData = new UISimpleData();
        public CalcWindow()
        {
            InitializeComponent();
            this.DataContext = _uiData;
        }
    }
}

ViewModels / UISimpleData.cs

using System;
using System.ComponentModel;
using System.Windows;

namespace DoubleToTextBlockBinding.ViewModels
{
    public class UISimpleData : INotifyPropertyChanged, IDataErrorInfo
    {
        private double _doubleField = 2.0;

        public double DoubleField
        {
            get
            {
                return _doubleField;
            }
            set
            {
                if (_doubleField == value)
                    return;

                _doubleField = value;
                RaisePropertyChanged("DoubleField");
            }
        }

        public string this[string propertyName]
        {
            get
            {
                string validationResult = null;
                switch (propertyName)
                {
                    case "DoubleField":
                        {
                            if (DoubleField < 0 || DoubleField > 5)
                                validationResult = "DoubleField is out of range";
                            break;
                        }
                    default:
                        throw new ApplicationException("Unknown Property being validated on UIData");
                }
                return validationResult;
            }
        }

        public string Error { get { return "Not Implemented"; } }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void RaisePropertyChanged(string property)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
            //MessageBox.Show("Changed to " + DoubleField);
        }
    }
}

预期行为:

  1. 将文本框的内容更改为“ 3”。

(您将在同一窗口上看到TextBlock更改为“ 3”。)

  1. 单击“确认”按钮。

  2. 出现一个新窗口。检查TextBlock的内容是否为“ 3”。

(实际结果在此处为“ 2”。)

...这是我目前能做的最好的。请帮我。谢谢。

1 个答案:

答案 0 :(得分:1)

您将在两个类中都创建视图模型的新实例。如果在MainWindow的viewmodel中更改了某些内容,则必须将此模型传递给CalcWindow。

我的猜测是您应该像这样编写CalcWindow的构造函数:

public CalcWindow(UISimpleData yourViewModelFromMainWindow)
{
    InitializeComponent();
    this.DataContext = yourViewModelFromMainWindow;
}

以及在MainWindow中的ConfirmButton_Click方法中

private void ConfirmButton_Click(object sender, RoutedEventArgs e)
{
    new CalcWindow(this.DataContext as UISimpleData).Show();
}

我希望这会有所帮助。如果不是,请随时询问。