C# WPF:单击数据网格中嵌入的按钮时,我想触发SelectionChanged,然后单击,但不能同时单击
我有一个DataGrid和一份员工名单。当用户更改所选行时,我希望代码隐藏执行一个昂贵的“加载”操作,从数据库中提取数据,并阻止用户在控件上的进一步输入,直到完成为止。这目前效果很好。每行还有一个按钮,按下时,我想要:C# WPF:单击数据网格中嵌入的按钮时,我想触发SelectionChanged,然后单击,但不能同时单击,c#,wpf,xaml,datagrid,race-condition,C#,Wpf,Xaml,Datagrid,Race Condition,我有一个DataGrid和一份员工名单。当用户更改所选行时,我希望代码隐藏执行一个昂贵的“加载”操作,从数据库中提取数据,并阻止用户在控件上的进一步输入,直到完成为止。这目前效果很好。每行还有一个按钮,按下时,我想要: 对于要选择的按下按钮的行 对于要加载的数据 函数“打印”启动,但直到数据加载函数返回 这是我的XAML: <Window x:Class="ListViewPrintProblem.MainWindow" xmlns="http://schemas.micr
<Window x:Class="ListViewPrintProblem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:listViewPrintProblem="clr-namespace:ListViewPrintProblem"
d:DataContext="{d:DesignInstance listViewPrintProblem:MainViewModel, IsDesignTimeCreatable=True}"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
DataContextChanged="MainWindow_OnDataContextChanged_OnDataContextChanged">
<Grid>
<DataGrid
x:Name="StaffList"
ItemsSource="{Binding StaffItems}"
GridLinesVisibility="Horizontal"
IsSynchronizedWithCurrentItem="True"
AutoGenerateColumns="False"
CanUserAddRows="False"
SelectedItem="{Binding SelectedStaffItem}">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Name="printButton">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=DataContext.PrintCommand}"
CommandParameter="{Binding ElementName=printButton, Path=Content}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction
Command="{Binding SelectedStaffChangedCommand}"
CommandParameter="{Binding Path=SelectedItem, ElementName=StaffList}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
</Grid>
</Window>
当用户单击一行时,加载将异步运行,并且不会阻止用户输入,这很好。但是,当用户单击打印图标时,加载将异步运行,并且不会阻止打印,这是不好的。因此,打印显示的是以前选择的员工的姓名,而不是当前员工的姓名。如果我从加载中删除Task.Delay,它每次都能正常工作。那么你的问题是什么?我如何实现解决方案1或2?最好是#1.发布您当前在单击按钮时调用的命令的实现。好的,发布了,并提供了更多关于出错原因的详细信息。
public string LoadedStaff { get; set; }
private void SelectedStaffChanged(Staff newStaff)
{
if (LoadedStaff == newStaff?.Name) return;
Task.Factory.StartNew(Load).GetAwaiter().GetResult();
}
private async void Load()
{
Loading = true;
LoadedStaff = await GetNameAsync(SelectedStaffItem);
Loading = false;
}
private static async Task<string> GetNameAsync(Staff selectedStaffItem)
{
await Task.Delay(1000);
switch (selectedStaffItem?.Name)
{
case "Moe":
return "Moe Howard";
case "Larry":
return "Larry Fine";
case "Curly":
return "Curly Howard";
default:
return "Unknown";
}
}
private void MainWindow_OnPrint()
{
var vm = DataContext as MainViewModel;
MessageBox.Show(vm?.LoadedStaff);
}