在打开的WPF窗口表单中更新数据

时间:2016-06-17 16:56:26

标签: c# wpf

我将数据从Form1的一个WPF窗口传输到Form2的另一个WPF窗口,但每次我将数据从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();
}

3 个答案:

答案 0 :(得分:1)

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

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

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);
        }


    }
}

答案 1 :(得分:0)

听起来你需要一个模态窗口。使用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

}

答案 2 :(得分:0)

以下是满足我需求的方法:

窗口1

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

Window 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();
    }
}