DataGrid中如何通过Trigger等方式实现右键选中Cell

saybookcat 2017-12-07 03:12:37
实现了一个DataGrid,选中时获得行和选中的单元格,通过右键菜单可以复制单元格的值,不过右键选中时 Cell不能被选中。
通过什么方式可以在xaml中实现右键选择cell时,先选中cell呢?


<Window.Resources>
<local:DataGridTextCellValueConverter x:Key="converter"/>

</Window.Resources>

<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>

<DataGrid ItemsSource="{Binding Persons}"
SelectedItem="{Binding CurrentRow}"
CurrentCell="{Binding CurrentText, Mode=OneWayToSource, Converter={StaticResource converter}}"
IsReadOnly="True"
SelectionMode="Single">
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Copy" Command="{Binding CopyCommand}" CommandParameter="{Binding CurrentText}"/>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>


DataGridTextCellValueConverter

public class DataGridTextCellValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var cellInfo = (DataGridCellInfo)value;
if (cellInfo==null || cellInfo.Column == null || cellInfo.Item == null) return string.Empty;
var cellControl = cellInfo.Column.GetCellContent(cellInfo.Item);
var textBlock = cellControl as TextBlock;
if (textBlock == null) return string.Empty;
return textBlock.Text;
}
}


引用了MvvmLight
MainViewModel

public class MainViewModel
{
public MainViewModel()
{
Persons = new ObservableCollection<PersonViewModel>();
Persons.Add(new PersonViewModel { Name = "ssss", Age = 12 });
Persons.Add(new PersonViewModel { Name = "xxxx", Age = 30 });
}

public ObservableCollection<PersonViewModel> Persons { get; set; }


private PersonViewModel currentRow;
public PersonViewModel CurrentRow
{
get
{
return currentRow;
}
set
{
currentRow = value;

if (currentRow != null)
{
Console.WriteLine("CurrentRow: Name = {0}, Age = {1} ",
currentRow.Name, currentRow.Age);
}
}
}

private string currentText;
public string CurrentText
{
get
{
return currentText;
}
set
{
currentText = value;
Console.WriteLine("CurrentText: " + currentText);
}
}

private ICommand _copyCommand;
public ICommand CopyCommand
{
get
{
if (_copyCommand == null)
{
_copyCommand = new RelayCommand<string>(OnCopyAction);
}
return _copyCommand;
}
}

private void OnCopyAction(string param)
{
if (string.IsNullOrWhiteSpace(param)) return;
Clipboard.Clear();
Clipboard.SetDataObject(param);
}
}
...全文
655 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
saybookcat 2017-12-07
  • 打赏
  • 举报
回复
补上

        private static DependencyObject VisualUpwardSearch<M>(DependencyObject source)
        {
            while (source != null && source.GetType() != typeof(M))
            {
                if (source is Visual || source is Visual3D)
                    source = VisualTreeHelper.GetParent(source);
                else
                    source = LogicalTreeHelper.GetParent(source);
            }
            return source;
        }
saybookcat 2017-12-07
  • 打赏
  • 举报
回复
SelectedItem 已经可以标记选中的是哪一行,这里主要的问题是 DataGrid SelectionUnit的问题 ,当前默认是CellOrRowHeader ,由于需要获得行 又获得列,只能设置这一种了。而在鼠标点击行的时候 Cell先被记录 ,然后 Row被记录 ,这时候由于 已经切换到Row选中模式,Cell选中将不被触发 。 我现在用了一种不太好的方式实现实现这部分功能。

            <i:Interaction.Triggers>
                <i:EventTrigger EventName="PreviewMouseRightButtonDown">
                    <command:EventToCommand Command="{Binding DataContext.SelectedCellItemCommand,
                        RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" PassEventArgsToCommand="True"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>

        private readonly ICommand _selectCellItemCommand = null;

        public ICommand SelectedCellItemCommand
        {
            get { return _selectCellItemCommand.Relay<RoutedEventArgs>(SelectedCellItemCmdAction); }
        }

        private void SelectedCellItemCmdAction(RoutedEventArgs e)
        {
            var dataGridCell = VisualUpwardSearch<DataGridCell>(e.OriginalSource as DependencyObject) as DataGridCell;

            if (dataGridCell == null) return;
            dataGridCell.Focus();
            e.Handled = true;
        }
  • 打赏
  • 举报
回复
右键点击的时候 DataGrid已经失去焦点,除非在数据类中手动增加一个选中属性,选择行的时候更改它的值为True,再根据Trigger判定它的值改变背景色。
内容概要:本文档是一份关于开发经典小游戏“贪吃蛇”的保姆级毕业设计指导文档,涵盖从游戏规则、功能设计、技术选型到核心代码实现的完整流程。文档以Python + Pygame为技术栈,详细讲解了游戏初始化、蛇的移动逻辑、食物生成、碰撞检测、计分与等级系统、键盘控制及主循环渲染等核心模块,并提供了完整的项目结构和源码示例。采用状态机管理游戏状态,使用列表模拟链表结构存储蛇身,结合方向缓冲机制优化操作体验,同时引入难度递增机制提升可玩性。文末还列举了飞机大战、扫雷、五子棋等同类课题作为拓展参考。; 适合人群:具备一定编程基础、正在进行毕业设计或课程设计的学生,尤其是对游戏开发感兴趣的初级开发者。; 使用场景及目标:①帮助学生独立完成一个功能完整、结构清晰的小游戏项目,用于毕业答辩或课程展示;②深入理解事件驱动编程、状态管理、碰撞检测、定时刷新等基础编程概念;③掌握Python + Pygame开发2D小游戏的核心技能,并具备二次开发与功能拓展能力。; 阅读建议:建议读者按照“规则→设计→代码→运行”的顺序逐步学习,动手实践每个模块并调试代码,重点关注方向缓冲、状态机、食物生成算法等设计细节,同时可尝试实现文末提出的拓展功能以增强项目亮点。

8,757

社区成员

发帖
与我相关
我的任务
社区描述
WPF/Silverlight相关讨论
社区管理员
  • WPF/Silverlight社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧