我有ListView一些行。您可以在列表中选择一个项目,然后您将获得详细视图(主详细信息视图)。
在详细信息视图中,我有一个按钮。当您单击一个按钮时,它会禁用它并执行一些昂贵的操作。
问题是由于某种原因,所有行的所有按钮都被禁用?我在这里错过了什么吗?
private void BtnGetStatus_Click(object sender, RoutedEventArgs e) {
Button btn = sender as Button;
if (btn.DataContext is ListCollectionView view) {
if (view.CurrentItem is MyViewModel viewModel) {
// Strange - Disables all buttons not currently clicked
btn.IsEnabled = false;
BackgroundWorker _worker = new BackgroundWorker() { WorkerReportsProgress = false };
_worker.DoWork += (se, ev) => {
// Simulate Expensive operation
System.Threading.Thread.Sleep(10000);
};
_worker.RunWorkerCompleted += (se, ev) => {
// Strange - enables all buttons not just clicked
btn.IsEnabled = true;
};
_worker.RunWorkerAsync();
}
}
}
这是一个演示该问题的简单示例。如果您单击一个按钮并转到其他行按钮将折叠。
只有点击过的应该是
XAML
<Window x:Class="WpfApp1.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:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate x:Key="detailsUserTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel>
<Button Name="BtnGetStatus" Click="BtnGetStatus_Click"
Content="Click to start Expensive Operation">
</Button>
</StackPanel>
</Grid>
</DataTemplate>
<CollectionViewSource
Source="{Binding Source={x:Static local:MainWindow.Users}}"
x:Key="dataViewSource" />
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView Name="lv_data"
ItemsSource="{Binding Source={StaticResource dataViewSource}}"
SelectionMode="Single">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding Path=UserID}"/>
<GridViewColumn Header="Username" DisplayMemberBinding="{Binding Path=Username}"/>
<GridViewColumn Header="Is Enabled" DisplayMemberBinding="{Binding Path=IsEnabled}"/>
</GridView>
</ListView.View>
</ListView>
<ContentControl Grid.Column="1"
Width="Auto"
ContentTemplate="{StaticResource detailsUserTemplate}"
Content="{Binding Source={StaticResource dataViewSource}}">
</ContentControl>
</Grid>
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public static ObservableCollection<User> Users
{
get
{
return new ObservableCollection<User>
{
new User {UserID = 1, Username = "user 1", IsEnabled = true},
new User {UserID = 2, Username = "User 2", IsEnabled =true},
new User {UserID = 3, Username = "Username 3", IsEnabled = true},
new User {UserID = 4, Username = "Username 4", IsEnabled = false}
};
}
}
private void BtnGetStatus_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
btn.IsEnabled = false;
btn.Visibility = Visibility.Collapsed;
BackgroundWorker worker = new BackgroundWorker()
{
WorkerReportsProgress = false
};
worker.DoWork += (se, ev) =>
{
// Simulate expensive
System.Threading.Thread.Sleep(10000);
};
worker.RunWorkerCompleted += (se, ev) =>
{
btn.IsEnabled = true;
btn.Visibility = Visibility.Visible;
};
worker.RunWorkerAsync();
}
}
public class User
{
public int UserID { get; set; }
public string Username { get; set; }
public bool IsEnabled { get; set; }
}
}