如何在另一个方法中动态更改 textBlock 的内容?
How to dynamically change the content of a textBlock inside another method?
我有一个由“搜索”按钮触发的搜索方法(扩展的 SQL 查询)。我希望在代码为 运行 时在 TextBlock 中显示“运行...”,并在结束时显示“完成”。理想情况下,几秒钟后“完成”消息也会被“空闲”消息取代。
我的 XAML 代码的相关部分是这样的:
<Button x:Name="MainButton" Click="searchButton_Click" Content="search" ... />
<TextBlock Name="status" Text="Idle" .../>
我的C#代码的相关部分如下:
namespace WpfApp5
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void searchButton_Click(object sender, RoutedEventArgs e)
{
this.status.Text="running...";
// make connection
string mySQLquery= "Do a lot of things here...";
// show the result in a datagrid
SqlCommand my_cmd = new SqlCommand(mySQLquery, conn);
DataTable mydt = new DataTable();
using (SqlDataAdapter a = new SqlDataAdapter(my_cmd))
{
a.Fill(mydt);
}
this.status.Text="done";
}
}
}
这段代码的作用是,当应用程序打开时,它在 TextBlock 中显示“空闲”,然后不更改它,直到搜索过程完成;然后显示“完成”。所以“运行”状态不会出现。
我想要一个对我的代码逻辑进行最少更改的解决方案。提前谢谢你。
您需要 运行 异步查询。在方法退出之前,WPF 不会更新 UI。
您可以将处理程序标记为异步并使用 Task.Run
进行 sql 查询:
private async void searchButton_Click(object sender, RoutedEventArgs e)
{
this.status.Text="running...";
// make connection
string mySQLquery= "Do a lot of things here...";
// show the result in a datagrid
SqlCommand my_cmd = new SqlCommand(mySQLquery, conn);
DataTable mydt = new DataTable();
await Task.Run(() => {
using (SqlDataAdapter a = new SqlDataAdapter(my_cmd))
{
a.Fill(mydt);
}
});
this.status.Text="done";
await Task.Delay(2000);
this.status.Text = "idle";
}
您是 运行 UI 线程上的 searchButton_click
函数,UI 在函数完成之前不会更新。
private void searchButton_Click(object sender, RoutedEventArgs e)
{
// starts the lambda outside the UI thread
Task.Run(() =>
{
// dispatcher will execute the lambda inside the UI thread
Application.Current.Dispatcher.Invoke(() =>
{
Status.Text = "running...";
});
Thread.Sleep(1000);
Application.Current.Dispatcher.Invoke(() =>
{
Status.Text = "done";
});
SetDefaultPromise();
});
}
private void SetDefaultPromise()
{
Task.Run(() =>
{
Thread.Sleep(1000);
Application.Current.Dispatcher.Invoke(() =>
{
Status.Text = "idle";
});
});
}
我有一个由“搜索”按钮触发的搜索方法(扩展的 SQL 查询)。我希望在代码为 运行 时在 TextBlock 中显示“运行...”,并在结束时显示“完成”。理想情况下,几秒钟后“完成”消息也会被“空闲”消息取代。
我的 XAML 代码的相关部分是这样的:
<Button x:Name="MainButton" Click="searchButton_Click" Content="search" ... />
<TextBlock Name="status" Text="Idle" .../>
我的C#代码的相关部分如下:
namespace WpfApp5
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void searchButton_Click(object sender, RoutedEventArgs e)
{
this.status.Text="running...";
// make connection
string mySQLquery= "Do a lot of things here...";
// show the result in a datagrid
SqlCommand my_cmd = new SqlCommand(mySQLquery, conn);
DataTable mydt = new DataTable();
using (SqlDataAdapter a = new SqlDataAdapter(my_cmd))
{
a.Fill(mydt);
}
this.status.Text="done";
}
}
}
这段代码的作用是,当应用程序打开时,它在 TextBlock 中显示“空闲”,然后不更改它,直到搜索过程完成;然后显示“完成”。所以“运行”状态不会出现。 我想要一个对我的代码逻辑进行最少更改的解决方案。提前谢谢你。
您需要 运行 异步查询。在方法退出之前,WPF 不会更新 UI。
您可以将处理程序标记为异步并使用 Task.Run
进行 sql 查询:
private async void searchButton_Click(object sender, RoutedEventArgs e)
{
this.status.Text="running...";
// make connection
string mySQLquery= "Do a lot of things here...";
// show the result in a datagrid
SqlCommand my_cmd = new SqlCommand(mySQLquery, conn);
DataTable mydt = new DataTable();
await Task.Run(() => {
using (SqlDataAdapter a = new SqlDataAdapter(my_cmd))
{
a.Fill(mydt);
}
});
this.status.Text="done";
await Task.Delay(2000);
this.status.Text = "idle";
}
您是 运行 UI 线程上的 searchButton_click
函数,UI 在函数完成之前不会更新。
private void searchButton_Click(object sender, RoutedEventArgs e)
{
// starts the lambda outside the UI thread
Task.Run(() =>
{
// dispatcher will execute the lambda inside the UI thread
Application.Current.Dispatcher.Invoke(() =>
{
Status.Text = "running...";
});
Thread.Sleep(1000);
Application.Current.Dispatcher.Invoke(() =>
{
Status.Text = "done";
});
SetDefaultPromise();
});
}
private void SetDefaultPromise()
{
Task.Run(() =>
{
Thread.Sleep(1000);
Application.Current.Dispatcher.Invoke(() =>
{
Status.Text = "idle";
});
});
}