【问题标题】:Update Data in opened WPF window form以打开的 WPF 窗口形式更新数据
【发布时间】:2016-06-19 02:39:56
【问题描述】:

我正在将数据从一个 WPF 窗口表单 Form1 传输到另一个 WPF 窗口表单 Form2,但每次我将数据从 Form2 传输到 Form1 时,我都必须关闭并打开 Form1。有没有在不关闭和打开Form1的情况下传输数据的替代方法?

FORM1

private void txtSellerCode_GotFocus(object sender, RoutedEventArgs e)
{
    SelectSeller frmSelectSeller = new SelectSeller();
    frmSelectSeller.Show();
    this.Hide();
}

FORM2

private void SelectBtn_Click(object sender, RoutedEventArgs e)
{
    DataRowView drv = (DataRowView)dataGridSeller.SelectedItem;
    clsCreateInvoice.S_ID = int.Parse(drv["B_ID"].ToString());
    clsCreateInvoice.S_Code = drv["B_Code"].ToString();
    clsCreateInvoice.S_Name_Address = drv["B_Name"].ToString() + " ," + 
    drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();

    CreateInvoice frmCreateInvoice = new CreateInvoice();
    frmCreateInvoice.txtSellerCode.Text = drv["B_Code"].ToString();
    frmCreateInvoice.lblSellerNameAddress.Text = drv["B_Name"].ToString() + " ," + 
    drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();
    frmCreateInvoice.Show();
    this.Hide();
}

【问题讨论】:

  • 你能把你的完整代码贴在这两个表单的文件后面吗?

标签: c# wpf


【解决方案1】:

在经常用于 WPF 应用程序的 MVVM 模式中,这可以通过多种方式实现。以下方法可能是最简单的:

1) 当前在您的代码隐藏文件中的代码将进入一种称为“ViewModel”的类。这是一个不依赖于任何面向 UI 的对象的类,而是充当 XAML 视图的“DataContext”。两者通过 Xaml 数据绑定表达式联系起来。为了让一个类至少成为 ViewModel,它必须实现 INotifyPropertyChanged 接口。 Form1 和 Form2 背后的代码都需要放入一个实现 INotifyPropertyChanged 的​​类中,称为 Form1ViewModel 和 Form2ViewModel。

2) Form1ViewModel 的实例可以订阅 Form2ViewModel 实例的更改,这样每次 Form1 属性发生更改时,Form2 中的处理程序都可以捕获更改并更新它自己的匹配属性

3) Form1View.xaml 和 Form2View.xaml 可以使用双向绑定表达式分别绑定到 Form1ViewModel.cs 和 Form2ViewModels.cs 的属性,这样每次 Form1ViewModel.MyProperty 更改(感谢来自 Form2ViewModel 的更新),任何绑定到 Form1ViewModel.MyProperty 的 UI 控件都将使用视图模型属性的新值进行更新。

编辑(如何在没有 MVVM 的情况下做这种事情):

我建议创建一个测试 WPF 项目。向名为“ChildWindow”的项目添加一个新窗口。将我的所有代码粘贴到文件中后,运行项目。单击按钮以“显示子窗体”。将两个窗口分开,以便它们可以并排查看。在 MainWindows TextBox 中输入一些文本,然后观察 ChildWindow 的文本框自动更新它的文本!

MainWindow.xaml:

<Window x:Class="Wpf_2FormSync.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" DataContext="{Binding RelativeSource={RelativeSource Self}}"
        >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="82*"/>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="10*"/>
        </Grid.RowDefinitions>
        <TextBox Text="{Binding MyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
        <Button Click="Button_Click_1" Grid.Row="1"  >Show Child Form</Button>
        <Button  Grid.Row="2" Click="Button_Click_2"  >Update Child Window</Button>
    </Grid>
</Window>

MainWindow.xaml.cs:

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


namespace Wpf_2FormSync
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private ChildWindow _childWindow = null;
        private string _myName = "";
        public string MyName
        {
            get { return _myName; }
            set
            {
                if (value == _myName) return;
                _myName = value;
                NotifyOfPropertyChanged("MyName");
                if (_childWindow != null)
                    _childWindow.MyName = value;
            }
        }
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            _childWindow = new ChildWindow();
            _childWindow.Show();
            _childWindow.MyName = "John";
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            if (_childWindow != null)
                _childWindow.MyName = this.MyName;
        }
    }
}

ChildWindow.xaml:

<Window x:Class="Wpf_2FormSync.ChildWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ChildWindow" Height="300" Width="300" DataContext="{Binding RelativeSource={RelativeSource Self}}" >
    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="112*"/>
            <RowDefinition Height="157*"/>
        </Grid.RowDefinitions>
        <TextBox Text="{Binding MyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0"></TextBox>
        <Button Grid.Row="1" Click="Button_Click_1">Show</Button>
    </Grid>
</Window>

ChildWindow.xaml.cs:

using System.ComponentModel;
using System.Windows;

namespace Wpf_2FormSync
{
    /// <summary>
    /// Interaction logic for ChildWindow.xaml
    /// </summary>
    public partial class ChildWindow : Window, INotifyPropertyChanged
    {
        private string _myName = "";
        public string MyName
        {
            get { return _myName; }
            set
            {
                if (value == _myName) return;
                _myName = value;
                NotifyOfPropertyChanged("MyName");
            }
        }

        public ChildWindow()
        {
            InitializeComponent();

        }

        public event PropertyChangedEventHandler PropertyChanged;

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

        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(MyName);
        }


    }
}

【讨论】:

  • 我对 WPF 很陌生,我正在学习。所以不太了解 WPF 以及 MVVM 模式。一些示例的更多帮助,将不胜感激。
  • 由于您正在开发 WPF 应用程序,我建议您 get started first。我无法想象有人在他不掌握或至少不了解它的基础知识的技术中发展。
  • Hey Seanthanx 为您提供帮助.....请给我推荐一个在线学习 WPF 和 MVVM 的好地方.....
【解决方案2】:

听起来你需要一个模态窗口。使用 ShowDialog() 而不是 Show()

这是你想要的行为吗?

FORM1:

private void txtSellerCode_GotFocus(object sender, RoutedEventArgs e)
{
    SelectSeller frmSelectSeller = new SelectSeller();
    frmSelectSeller.ShowDialog();
    this.txtSellerCode.Text = frmSelectSeller.SellerCode;
    this.lblSellerNameAddress.Text = frmSelectSeller.SellerNameAddress

}

FORM2:
//add these public properties
public string SellerCode {get; set;}
public string SellerNameAddress {get; set;}

private void SelectBtn_Click(object sender, RoutedEventArgs e)
{
    DataRowView drv = (DataRowView)dataGridSeller.SelectedItem;
    clsCreateInvoice.S_ID = int.Parse(drv["B_ID"].ToString());
    clsCreateInvoice.S_Code = drv["B_Code"].ToString();
    clsCreateInvoice.S_Name_Address = drv["B_Name"].ToString() + " ," + drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();

    SellerCode = drv["B_Code"].ToString();
    SellerNameAddress = drv["B_Name"].ToString() + " ," + drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();

    this.Close();

}

如果您需要在 form2 可见时隐藏 Form1

private void txtSellerCode_GotFocus(object sender, RoutedEventArgs e)
{
    SelectSeller frmSelectSeller = new SelectSeller();
    this.Hide();
    frmSelectSeller.ShowDialog();
    this.Show();
    this.txtSellerCode.Text = frmSelectSeller.SellerCode;
    this.lblSellerNameAddress.Text = frmSelectSeller.SellerNameAddress

}

【讨论】:

  • 我认为 OP 想要看到的是 Form1 上的信息如何在 Form2 发生更改后更新,而无需关闭表单并重新打开它。 ShowDialog 与 Show 和 Show/Hide 并没有满足这个要求。
【解决方案3】:

这是我满足我需求的方法:

窗口 1

private void txtSellerCode_GotFocus(object sender, RoutedEventArgs e) 
{ 
SelectSeller frmSelectSeller = new SelectSeller(this); 
frmSelectSeller.Show(); 
this.Hide(); 
} 

窗口 2

public partial class SelectSeller : Window
{
    CreateInvoice _frmCreateInvoice;
    public SelectSeller(CreateInvoice frmCreateInvoice)
    {
        InitializeComponent();
 _frmCreateInvoice = frmCreateInvoice;
    }

    private void SelectBtn_Click(object sender, RoutedEventArgs e)
    {
        DataRowView drv = (DataRowView)dataGridSeller.SelectedItem;
        clsCreateInvoice.S_ID = int.Parse(drv["B_ID"].ToString());
        clsCreateInvoice.S_Code = drv["B_Code"].ToString();
        clsCreateInvoice.S_Name_Address = drv["B_Name"].ToString() + " ," + drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();

        _frmCreateInvoice.txtSellerCode.Text = drv["B_Code"].ToString();
        _frmCreateInvoice.lblSellerNameAddress.Text = drv["B_Name"].ToString() + " ," + drv["B_Address_1"].ToString() + " ," + drv["B_Address_2"].ToString();
        this.Hide();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2015-03-03
    • 2013-09-16
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    相关资源
    最近更新 更多