簡體   English   中英

當SelectionMode =“ Extended”時,DataGrid無法正確取消選擇隱藏項

[英]DataGrid doesn't deselect hidden items properly when SelectionMode=“Extended”

WPF DataGrid出現問題,這使我發瘋。 讓我們考慮一下這種視圖模型:

public class ViewModel : INotifyPropertyChanged
{
    public int Id { get; set; }
    public string Name { get; set; }

    public bool IsSelected 
    {
        get { return isSelected; }
        set
        {
            System.Diagnostics.Debug.WriteLine("{0}'s IsSelected new value is: {1}", Name, value);
            if (isSelected != value)
            {
                isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }
    }
    private bool isSelected;

    // INPC implementation
}

...此XAML:

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <DataGrid ItemsSource="{Binding}" IsReadOnly="True" AutoGenerateColumns="False" 
                  SelectionMode="Extended" SelectionUnit="FullRow">
            <DataGrid.ItemContainerStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
                </Style>
            </DataGrid.ItemContainerStyle>

            <DataGrid.Columns>
                <DataGridCheckBoxColumn Header="Is selected" Binding="{Binding IsSelected}"/>
                <DataGridTextColumn Header="Id" Binding="{Binding Id}"/>
                <DataGridTextColumn Header="Name" Width="*" Binding="{Binding Name}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

...以及以下代碼:

public partial class MainWindow : Window
{
    private IList<ViewModel> GenerateViewModels()
    {
        var viewModels = new List<ViewModel>();

        for (var i = 0; i < 100; i++)
        {
            viewModels.Add(new ViewModel
            {
                Id = i,
                Name = string.Format("Item {0}", i)
            });
        }

        return viewModels;
    }

    public MainWindow()
    {
        InitializeComponent();
        DataContext = GenerateViewModels();
    }
}

情況1。

  • 選擇項目0。選擇項目0,選中復選框。
  • 滾動網格的內容以隱藏項目0。讓項目6位於可見區域的頂部。
  • 選擇項目10。選擇項目10,選中復選框。
  • 向上滾動到項目0。
  • 選擇項目0。選擇項目10, 選中該復選框。

調試輸出:

Item 0's IsSelected new value is: True
Item 0's IsSelected new value is: False
Item 10's IsSelected new value is: True
Item 10's IsSelected new value is: False

截圖:

情況2

  • 重新啟動應用程序。
  • 選擇網格頂部的幾個項目(例如,前三個項目)。 選中項目,選中復選框。
  • 滾動網格的內容以隱藏項目0。讓項目6位於可見區域的頂部。
  • 選擇項目10。選擇項目10,選中復選框。
  • 向上滾動到項目0。
  • 項目0和項目1 仍被選中 沒有檢查項目2。 沒有選擇所有三個第一項。

調試輸出:

Item 0's IsSelected new value is: True
Item 1's IsSelected new value is: True
Item 2's IsSelected new value is: True
Item 2's IsSelected new value is: False
Item 10's IsSelected new value is: True

截圖:

當擴展選擇模式時,問題正在重現。 當它是單個時,一切正常。

問題:
1.我想念什么嗎? 2.有人知道解決方法嗎?

更新

我為網格添加了SelectionChanged事件處理程序:

    private void MyGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems != null)
        {
            foreach (var item in e.AddedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is added to selection.", item.Id);
            }
        }
        if (e.RemovedItems != null)
        {
            foreach (var item in e.RemovedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is removed from selection.", item.Id);
            }
        }

        e.Handled = true;
    }

調試輸出顯示, SelectedItems集合已正確更新。 例如,對於第一種情況,輸出為:

Item 0's IsSelected new value is: True
** Item 0 is added to selection.
Item 0's IsSelected new value is: False
Item 10's IsSelected new value is: True
** Item 10 is added to selection.
** Item 0 is removed from selection.
Item 10's IsSelected new value is: False
** Item 0 is added to selection.
** Item 10 is removed from selection.

但是綁定數據屬性IsSelected不會更新!

至少找到了一種解決方法,它與問題的更新有關。
讓我們對SelectionChanged事件處理程序進行一些修改:

    private void MyGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems != null)
        {
            foreach (var item in e.AddedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is added to selection.", item.Id);

                if (!item.IsSelected)
                {
                    // if bound data item still isn't selected, fix this
                    item.IsSelected = true;
                }
            }
        }
        if (e.RemovedItems != null)
        {
            foreach (var item in e.RemovedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is removed from selection.", item.Id);

                if (item.IsSelected)
                {
                    // if bound data item still is selected, fix this
                    item.IsSelected = false;
                }
            }
        }

        e.Handled = true;
    }

但這絕對是DataGrid的錯誤,不是嗎?

我嘗試了一下,我認為您需要同時將isSelected設置為false。 這個對我有用。 但是感謝您的最初解決方案! 這對我幫助很大。

private void MyGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems != null)
        {
            foreach (var item in e.AddedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is added to selection.", item.Id);

                if (!item.IsSelected)
                {
                    // if bound data item still isn't selected, fix this
                    item.IsSelected = false;
                }
            }
        }
        if (e.RemovedItems != null)
        {
            foreach (var item in e.RemovedItems.Cast<ViewModel>())
            {
                System.Diagnostics.Debug.WriteLine("** Item {0} is removed from selection.", item.Id);

                if (item.IsSelected)
                {
                    // if bound data item still is selected, fix this
                    item.IsSelected = false;
                }
            }
        }

        e.Handled = true;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM