Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xxx #1

Open
laiqun opened this issue Feb 20, 2023 · 10 comments
Open

xxx #1

laiqun opened this issue Feb 20, 2023 · 10 comments

Comments

@laiqun
Copy link
Owner

laiqun commented Feb 20, 2023

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Student List" Height="250" Width="350">
    <Grid>
        <DataGrid x:Name="studentGrid" Margin="10" AutoGenerateColumns="False" ItemsSource="{Binding Students}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                <DataGridTextColumn Header="Age" Binding="{Binding Age}" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // 创建一个包含 Student 对象的可观察列表
            var students = new ObservableCollection<Student>()
            {
                new Student() { Name = "Alice", Age = 20 },
                new Student() { Name = "Bob", Age = 21 },
                new Student() { Name = "Charlie", Age = 22 },
            };

            // 将列表绑定到 DataGrid 的 ItemsSource 属性
            DataContext = new MainViewModel() { Students = students };
        }
    }

    public class MainViewModel
    {
        public ObservableCollection<Student> Students { get; set; }
    }

    public class Student : INotifyPropertyChanged
    {
        private string name;
        private int age;

        public string Name
        {
            get => name;
            set
            {
                if (name != value)
                {
                    name = value;
                    NotifyPropertyChanged(nameof(Name));
                }
            }
        }

        public int Age
        {
            get => age;
            set
            {
                if (age != value)
                {
                    age = value;
                    NotifyPropertyChanged(nameof(Age));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

<Window x:Class="WpfApp1.MainWindow"
        ...
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
    <Grid>
        <DataGrid x:Name="studentGrid" Margin="10" AutoGenerateColumns="False" ItemsSource="{Binding Students}">
            ...
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </DataGrid>
    </Grid>
</Window>

@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Collections.Specialized;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // 创建一个包含 Student 对象的可观察列表
            var students = new ObservableCollection<Student>()
            {
                new Student() { Name = "Alice", Age = 20 },
                new Student() { Name = "Bob", Age = 21 },
                new Student() { Name = "Charlie", Age = 22 },
            };

            // 将列表绑定到 DataGrid 的 ItemsSource 属性
            DataContext = new MainViewModel() { Students = students };
        }
    }

    public class MainViewModel : ViewModelBase
    {
        private readonly RelayCommand selectionChangedCommand;

        public MainViewModel()
        {
            Students.CollectionChanged += OnStudentsChanged;
            selectionChangedCommand = new RelayCommand(OnSelectionChanged);
        }

        public ObservableCollection<Student> Students { get; set; }

        public ICommand SelectionChangedCommand => selectionChangedCommand;

        private void OnSelectionChanged()
        {
            foreach (var item in Students)
            {
                item.IsSelected = false;
            }

            foreach (var item in Students.Where(x => x.Equals(SelectedStudent)))
            {
                item.IsSelected = true;
            }
        }

        private void OnStudentsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Move)
            {
                var movedItem = Students[e.OldStartingIndex];
                Students.RemoveAt(e.OldStartingIndex);
                Students.Insert(e.NewStartingIndex, movedItem);
            }
        }

        public Student SelectedStudent { get; set; }
    }

    public class Student : INotifyPropertyChanged
    {
        private string name;
        private int age;
        private bool isSelected;

        public string Name
        {
            get => name;
            set
            {
                if (name != value)
                {
                    name = value;
                    NotifyPropertyChanged(nameof(Name));
                }
            }
        }

        public int Age
        {
            get => age;
            set
            {
                if (age != value)
                {
                    age = value;
                    NotifyPropertyChanged(nameof(Age));
                }
            }
        }

        public bool IsSelected
        {
            get => isSelected;
            set
            {
                if (isSelected != value)
                {
                    isSelected = value;
                    NotifyPropertyChanged(nameof(IsSelected));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace WpfApp1
{
    public class VirtualList : IList, INotifyPropertyChanged
    {
        private readonly int count;
        private readonly Random random = new Random();

        public VirtualList(int count)
        {
            this.count = count;
        }

        public int Count => count;

        public bool IsFixedSize => true;

        public bool IsReadOnly => true;

        public bool IsSynchronized => false;

        public object SyncRoot => this;

        public object this[int index]
        {
            get => new Student() { Name = $"Student {index}", Age = random.Next(18, 30) };
            set => throw new NotImplementedException();
        }

        public int Add(object value)
        {
            throw new NotImplementedException();
        }

        public void Clear()
        {
            throw new NotImplementedException();
        }

        public bool Contains(object value)
        {
            throw new NotImplementedException();
        }

        public void CopyTo(Array array, int index)
        {
            throw new NotImplementedException();
        }

        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < count; i++)
            {
                yield return this[i];
            }
        }

        public int IndexOf(object value)
        {
            throw new NotImplementedException();
        }

        public void Insert(int index, object value)
        {
            throw new NotImplementedException();
        }

        public void Remove(object value)
        {
            throw new NotImplementedException();
        }

        public void RemoveAt(int index)
        {
            throw new NotImplementedException();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class Student
    {
        public string Name { get; set; }

        public int Age { get; set; }
    }
}

@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

<Window x:Class="WpfApp1.MainWindow"
        ...
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
    <Grid>
        <DataGrid x:Name="studentGrid" Margin="10" AutoGenerateColumns="False" ItemsSource="{Binding}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                <DataGridTextColumn Header="Age" Binding="{Binding Age}" />
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

XAML 代码:

```xml
<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp1"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <DataGrid x:Name="studentGrid" AutoGenerateColumns="False" CanUserAddRows="False" ItemsSource="{Binding}" RowHeaderWidth="0" SelectionMode="Single">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" />
                <DataGridTextColumn Header="Age" Binding="{Binding Age}" />
            </DataGrid.Columns>
            <DataGrid.RowStyle>
                <Style TargetType="DataGridRow">
                    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnPreviewMouseLeftButtonDown" />
                    <EventSetter Event="PreviewMouseLeftButtonUp" Handler="OnPreviewMouseLeftButtonUp" />
                    <EventSetter Event="PreviewMouseMove" Handler="OnPreviewMouseMove" />
                </Style>
            </DataGrid.RowStyle>
        </DataGrid>
    </Grid>
</Window>

@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = new VirtualList(10);

            studentGrid.PreviewMouseMove += StudentGrid_PreviewMouseMove;
            studentGrid.Drop += StudentGrid_Drop;
        }

        private int dragIndex = -1;
        private int dropIndex = -1;
        private Point startPoint;

        private void StudentGrid_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && dragIndex != -1)
            {
                Point currentPoint = e.GetPosition(studentGrid);
                double distance = (startPoint - currentPoint).Length;
                if (distance > 10)
                {
                    DataObject dataObject = new DataObject();
                    dataObject.SetData("index", dragIndex);
                    DragDrop.DoDragDrop(studentGrid, dataObject, DragDropEffects.Move);
                }
            }
        }

        private void StudentGrid_Drop(object sender, DragEventArgs e)
        {
            int index = (int)e.Data.GetData("index");

            if (dropIndex != -1 && dropIndex != index)
            {
                VirtualList list = (VirtualList)DataContext;

                object temp = list[index];
                if (dropIndex > index)
                {
                    for (int i = index; i < dropIndex; i++)
                    {
                        list[i] = list[i + 1];
                    }
                }
                else
                {
                    for (int i = index; i > dropIndex; i--)
                    {
                        list[i] = list[i - 1];
                    }
                }
                list[dropIndex] = temp;
            }
            dragIndex = -1;
            dropIndex = -1;
        }

        private void OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            dragIndex = ((DataGridRow)sender).GetIndex();
            startPoint = e.GetPosition(studentGrid);
        }

        private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            dragIndex = -1;
        }

        private void OnPreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && dragIndex != -1)
            {
                Point currentPoint = e.GetPosition(studentGrid);
                double distance = (startPoint - currentPoint).Length;
                if (distance > 10)
                {
                    dropIndex = GetDropIndex(e.GetPosition(studentGrid));
                }
            }
        }

        private int GetDropIndex(Point position)
        {
            int index

@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

    private int GetDropIndex(Point position)
    {
        int index = -1;
        for (int i = 0; i < studentGrid.Items.Count; i++)
        {
            DataGridRow row = (DataGridRow)studentGrid.ItemContainerGenerator.ContainerFromIndex(i);
            if (row != null)
            {
                Rect bounds = VisualTreeHelper.GetDescendantBounds(row);
                bounds.Location = row.TranslatePoint(bounds.Location, studentGrid);

                if (position.Y >= bounds.Top && position.Y < bounds.Bottom)
                {
                    index = i;
                    break;
                }
            }
        }
        return index;
    }
}

@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

private void DataGrid_PreviewMouseMove(object sender, MouseEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed)
    {
        MyData selectedData = dataGrid.SelectedItem as MyData;
        if (selectedData != null)
        {
            DataObject dragData = new DataObject(typeof(MyData), selectedData);
            DragDrop.DoDragDrop(dataGrid, dragData, DragDropEffects.Move);
        }
    }
}

private void DataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    dataGrid.AllowDrop = true;
}

private void DataGrid_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    dataGrid.AllowDrop = false;
}
private void DataGrid_Drop(object sender, DragEventArgs e)
{
    MyData draggedData = e.Data.GetData(typeof(MyData)) as MyData;
    MyData targetData = (e.OriginalSource as FrameworkElement).DataContext as MyData;

    int targetIndex = dataList.IndexOf(targetData);
    int draggedIndex = dataList.IndexOf(draggedData);

    if (targetIndex != draggedIndex)
    {
        dataList.Move(draggedIndex, targetIndex);
    }
}

@laiqun
Copy link
Owner Author

laiqun commented Feb 20, 2023

<DataGrid x:Name="dataGrid" AllowDrop="True"
          PreviewMouseMove="DataGrid_PreviewMouseMove"
          PreviewMouseLeftButtonDown="DataGrid_PreviewMouseLeftButtonDown"
          PreviewMouseLeftButtonUp="DataGrid_PreviewMouseLeftButtonUp"
          Drop="DataGrid_Drop" />

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant