查看看似忽略可见性的转换器输出
View Seemingly Ignoring Visibility Converter Output
我是 WPF 应用程序的新手,但这似乎是一件很简单的错误,让我很困惑。我试图寻找答案,但我发现的大部分是绑定错误,而这里不是这种情况。
本质上,我有一个 WPF 应用程序访问数据库以向用户显示项目。所述数据保存在视图的网格中,其可见性由实现 OnPropertyChanged 和标准 BoolToVisibility 转换器的布尔值 属性 (RecordLoaded) 确定。
DataView.xaml:
<Grid Visibility="{Binding RecordLoaded, Converter={StaticResource BoolToVisibility}}">
当树视图上的项目被选择时,SelectedRecord class 被更新,然后依次触发一个事件 (OnRecordSelected) 将 RecordLoaded 设置为 false 并调用一个函数 (FillDetails) 来获取相关的数据.
private void DataSelectedRecord_OnRecordSelected(object sender, EventArgs e)
{
RecordLoaded = false;
FillDetails();
}
从数据库中抓取所有数据后,在 FillDetails 结束时,RecordLoaded 设置为 true。
问题是,我正在尝试实现一些 'flicker' 以通过打开和关闭网格的可见性来表示视图已更新,尤其是在处理具有最小值的数据时两条记录之间的差异。但是,虽然我可以使用转换器将网格从初始 Visibility.Hidden 状态移动到可见状态,并且转换器在整个过程中都能正常工作,当布尔值设置为 false 和 true 时返回正确的 Hidden 或 Visible,但有从事物的视觉方面绝对没有变化,甚至没有闪烁。
我的第一个想法是状态很快变回真,以至于无法检测到,但我在布尔值之前的 FillDetails 方法中添加了一个延迟,没有任何乐趣。
有没有人对可能出现的问题有任何建议,或者甚至可能表示数据已更新的替代方式(没有干扰消息或其他方式)?
一切都在 UI 线程中同步发生,因此 UI 没有机会更新。您可以在任务中声明事件处理程序异步,运行 FillDetails 并等待它:
private async void DataSelectedRecord_OnRecordSelected(object sender, EventArgs e)
{
RecordLoaded = false;
await Task.Run(() => FillDetails());
RecordLoaded = true;
}
但是请注意,当 FillDetails 访问 UI 元素或 UI 元素绑定到的数据时,可能需要在 Dispatcher.Invoke
或 BeginInvoke
调用中执行此操作.
如果数据库 API 允许异步访问,您也许还可以声明 FillDetails async 并等待异步 API 调用。那么你就不需要 Task.Run:
private async void DataSelectedRecord_OnRecordSelected(object sender, EventArgs e)
{
RecordLoaded = false;
await FillDetails();
RecordLoaded = true;
}
private async Task FillDetails()
{
var queryResults = await someDbApiCallAsync();
// do something with it
}
我是 WPF 应用程序的新手,但这似乎是一件很简单的错误,让我很困惑。我试图寻找答案,但我发现的大部分是绑定错误,而这里不是这种情况。
本质上,我有一个 WPF 应用程序访问数据库以向用户显示项目。所述数据保存在视图的网格中,其可见性由实现 OnPropertyChanged 和标准 BoolToVisibility 转换器的布尔值 属性 (RecordLoaded) 确定。
DataView.xaml:
<Grid Visibility="{Binding RecordLoaded, Converter={StaticResource BoolToVisibility}}">
当树视图上的项目被选择时,SelectedRecord class 被更新,然后依次触发一个事件 (OnRecordSelected) 将 RecordLoaded 设置为 false 并调用一个函数 (FillDetails) 来获取相关的数据.
private void DataSelectedRecord_OnRecordSelected(object sender, EventArgs e)
{
RecordLoaded = false;
FillDetails();
}
从数据库中抓取所有数据后,在 FillDetails 结束时,RecordLoaded 设置为 true。
问题是,我正在尝试实现一些 'flicker' 以通过打开和关闭网格的可见性来表示视图已更新,尤其是在处理具有最小值的数据时两条记录之间的差异。但是,虽然我可以使用转换器将网格从初始 Visibility.Hidden 状态移动到可见状态,并且转换器在整个过程中都能正常工作,当布尔值设置为 false 和 true 时返回正确的 Hidden 或 Visible,但有从事物的视觉方面绝对没有变化,甚至没有闪烁。
我的第一个想法是状态很快变回真,以至于无法检测到,但我在布尔值之前的 FillDetails 方法中添加了一个延迟,没有任何乐趣。
有没有人对可能出现的问题有任何建议,或者甚至可能表示数据已更新的替代方式(没有干扰消息或其他方式)?
一切都在 UI 线程中同步发生,因此 UI 没有机会更新。您可以在任务中声明事件处理程序异步,运行 FillDetails 并等待它:
private async void DataSelectedRecord_OnRecordSelected(object sender, EventArgs e)
{
RecordLoaded = false;
await Task.Run(() => FillDetails());
RecordLoaded = true;
}
但是请注意,当 FillDetails 访问 UI 元素或 UI 元素绑定到的数据时,可能需要在 Dispatcher.Invoke
或 BeginInvoke
调用中执行此操作.
如果数据库 API 允许异步访问,您也许还可以声明 FillDetails async 并等待异步 API 调用。那么你就不需要 Task.Run:
private async void DataSelectedRecord_OnRecordSelected(object sender, EventArgs e)
{
RecordLoaded = false;
await FillDetails();
RecordLoaded = true;
}
private async Task FillDetails()
{
var queryResults = await someDbApiCallAsync();
// do something with it
}