当我在 WPF(.NET Core)中单击第二个窗口的“确定”按钮时,禁用 MainWindow 按钮并返回到 MainWindow 的初始状态
Posted
技术标签:
【中文标题】当我在 WPF(.NET Core)中单击第二个窗口的“确定”按钮时,禁用 MainWindow 按钮并返回到 MainWindow 的初始状态【英文标题】:Disable button of MainWindow and return to the initial state of MainWindow when I click an "OK" button of a Second Window in WPF (.NET Core) 【发布时间】:2021-01-09 09:09:30 【问题描述】:我在 WPF 应用程序中有两个窗口。第一个是 MainWindow,而第二个是 SecondaryWindow,它在 MainWindow 中填充数据。
简而言之,我的 MainWindow 中有一个“加载”按钮,该按钮被禁用,只有在用户浏览本地文件时才会启用。启用“加载”后,会要求用户填写一些凭据以将数据加载到 SQL Server 中的表中。当用户在第二个窗口中单击“确定”时,我希望 MainWindow 返回其初始状态。
MainWindow.xaml.cs 文件
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Data;
using System.IO;
namespace TestEnvironment
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public static class StringExtensions
public static string Args(this string str, params object[] args)
return String.Format(str, args);
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
// Functions - Methods
public DataTable ConvertToDataTable(string filePath)
DataTable tbl = new DataTable();
// Take the first 10 lines
var lines = File.ReadLines(filePath).Take(10);
// Split each line and create an integer sequence where each value
// is the number of the splitted elements
// then get the max value present in this sequence
var max = lines.Select(x => x.Split('\t').Length).Max();
// First line contains headers
string[] headers = lines.First().Split('\t');
// Now create the table with the max number of columns present
for (int col = 0; col < max; col++)
tbl.Columns.Add(headers[col], typeof(string));
//Use the Rows.Add method that accepts an object array
foreach (string line in lines.Skip(1))
tbl.Rows.Add(line.Split('\t'));
//UTF-8 encoding
/*var utf8 = Encoding.UTF8;
foreach (string line in lines.Skip(1))
IEnumerable<string> utf8Values = line.Split('\t')
.Select(s => utf8.GetString(Encoding.Convert(Encoding.ASCII, utf8,
Encoding.ASCII.GetBytes(s))));
tbl.Rows.Add(utf8Values);
*/
/*foreach (DataRow dr in tbl.Rows)
Debug.WriteLine(dr["Nationality"]);
string s = dr["Nationality"].ToString();
byte[] bytes = Encoding.Default.GetBytes(s);
dr["Nationality"] = Encoding.UTF8.GetString(bytes);
Debug.WriteLine(dr["Nationality"]);
*/
return tbl;
public static void WriteDataToFile(DataTable submittedDataTable, string submittedFilePath)
int i = 0;
StreamWriter sw = null;
sw = new StreamWriter(submittedFilePath, false);
for (i = 0; i < submittedDataTable.Columns.Count - 1; i++)
sw.Write(submittedDataTable.Columns[i].ColumnName + ";");
sw.Write(submittedDataTable.Columns[i].ColumnName);
sw.WriteLine();
foreach (DataRow row in submittedDataTable.Rows)
object[] array = row.ItemArray;
for (i = 0; i < array.Length - 1; i++)
sw.Write(array[i].ToString() + ";");
sw.Write(array[i].ToString());
sw.WriteLine();
sw.Close();
public static void SubmitData(string connectionString, string tablenametext)
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
sqlConnection.Open();
using (var command = sqlConnection.CreateCommand())
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "createselectedtableinDB";
command.Parameters.AddWithValue("@TableName", tablenametext);
command.ExecuteNonQuery();
public static string CreateConnectionString(string servernametext, string databasenametext)
string connectionstring = "Server=0;Database=1;Integrated Security=SSPI".Args(servernametext, databasenametext);
return connectionstring;
// Object Interactions
private void BrowseButton_Click(object sender, RoutedEventArgs e)
// Create OpenFileDialog
Microsoft.Win32.OpenFileDialog openFileDlg = new Microsoft.Win32.OpenFileDialog();
// Launch OpenFileDialog by calling ShowDialog method
Nullable<bool> result = openFileDlg.ShowDialog();
// Get the selected file name and display in a TextBox.
// Load content of file in a TextBlock
if (result == true)
FileNameTextBox.Text = openFileDlg.FileName;
TextBlock1.Text = "Created on: " + File.GetCreationTime(openFileDlg.FileName).ToString() +"\n";
Debug.WriteLine(File.GetCreationTime(openFileDlg.FileName).ToString());
var datatablematrix = ConvertToDataTable(filePath: openFileDlg.FileName);
/*Debug.WriteLine(datatablematrix);
WriteDataToFile(datatablematrix, @"C:\Users\spano\Desktop\ApplicationOption2\testdummy.txt");*/
grid.DataContext = datatablematrix.DefaultView;
// Set filter for file extension and default file extension
openFileDlg.DefaultExt = ".txt";
openFileDlg.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
Debug.WriteLine("Txt imported");
// Set initial directory
openFileDlg.InitialDirectory = @"C:\Documents\";
// Multiple selection with all file types
openFileDlg.Multiselect = true;
BrowseButton.IsEnabled = true;
LoadButton.IsEnabled = true;
Debug.WriteLine("End!");
private void LoadButton_Click(object sender, RoutedEventArgs e)
TableNamePopupwindow popup = new TableNamePopupwindow();
//ShowDialog means you can't focus the parent window, only the popup
popup.ShowDialog(); //execution will block here in this method until the popup closes
string resultTable = popup.TableNameValue;
string resultServer = popup.ServerNameValue;
string resultDatabase = popup.DatabaseNameValue;
var connectionString = CreateConnectionString(resultServer, resultDatabase);
SubmitData(connectionString, resultTable);
private void PowerButton_Click(object sender, RoutedEventArgs e)
App.Current.Shutdown();
private void MinimizeButton_Click(object sender, RoutedEventArgs e)
this.WindowState = WindowState.Minimized;
private void TabablzControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
TableNamePopupwindow.xaml.cs
using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Data;
using System.IO;
namespace TestEnvironment
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class TableNamePopupwindow : Window
public string TableNameValue
get
if (TableName == null) return string.Empty;
return TableName.Text;
public string ServerNameValue
get
if (ServerName == null) return string.Empty;
return ServerName.Text;
public string DatabaseNameValue
get
if (DatabaseName == null) return string.Empty;
return DatabaseName.Text;
public TableNamePopupwindow()
InitializeComponent();
private void OnOk_Click(object sender, RoutedEventArgs e)
//code I found here: https://***.com/questions/46089017/wpf-passing-text-from-one-window-to-another-window
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
mainWindow.LoadButton.IsEnabled = false;
this.Close();
正如您在上面看到的 OnOK 单击我希望重新禁用“加载按钮”。
MainWindow 的屏幕截图(用户打开应用时的初始状态)
MainWindow 的屏幕截图(用户浏览文件)
SecondWindow 的屏幕截图(当用户点击“加载”按钮时)
我想要的是当用户单击“确定”按钮关闭第二个窗口时 MainWindow 返回其初始状态(附上第一个屏幕截图)。 根据我在SO question 上找到的第二个窗口的代码,我设法返回初始状态,但每次单击“确定”按钮时都会打开一个新的 MainWindow。
【问题讨论】:
您解决了encoding 问题吗? @mm8 还没有。如果您想了解有关我发布的 SO 问题的更多信息,请通知我,因为我不确定我提供的材料是否足够。 您的问题是如何在MainWindow
中设置Button
的IsEnabled
属性?
@mm8 是的,实际上这是我尝试过的,但没有运气。我希望当用户浏览文件并加载文件后,再次禁用“加载”按钮并清除 DataGrid 中的数据(如我上传的第一个屏幕截图)。所以它就像一个循环 Screenshot 1->2->3->1
【参考方案1】:
与其在OnOk_Click
处理程序中打开MainWindow
的新实例,不如修改已经存在并打开的实例。
您需要以某种方式获得对它的引用。例如,您可以在打开 TableNamePopupwindow
时将其注入引用:
private readonly MainWindow _mainWindow;
public TableNamePopupwindow(MainWindow mainWindow)
InitializeComponent();
_mainWindow = mainWindow;
private void OnOk_Click(object sender, RoutedEventArgs e)
_mainWindow.LoadButton.IsEnabled = false;
this.Close();
主窗口:
TableNamePopupwindow popup = new TableNamePopupwindow(this);
popup.ShowDialog();
【讨论】:
以上是关于当我在 WPF(.NET Core)中单击第二个窗口的“确定”按钮时,禁用 MainWindow 按钮并返回到 MainWindow 的初始状态的主要内容,如果未能解决你的问题,请参考以下文章