【问题标题】:Setting datagrid's highlighted cell in xaml在 xaml 中设置 datagrid 的突出显示单元格
【发布时间】:2014-02-25 08:48:02
【问题描述】:

我的应用程序中有一个 DataGrid 和一个 ListView。 ListView 提供有关数据网格的选定项的信息。我在该 ListView 中放置了一个 HyperLink,它应该将数据网格的选定项更改为当前选定项的“父项”。

我的方法是在我的代码后面设置SelectedItem。一切正常,但数据网格没有突出显示新的选定项目。但我可以清楚地看到它被选中是因为它的灰色背景色消失了。是否可以通过编程设置突出显示的单元格?

<ListView>
    <TextBlock Text="{Binding SelectedParameter.Definition.Name, StringFormat=Name: {0:C}}" 
               TextWrapping="Wrap"/>
    <TextBlock Text="{Binding SelectedParameter.Definition.Type, StringFormat=Datentyp: {0:C}}" 
                               TextWrapping="Wrap"/>
               TextWrapping="Wrap"/>
    <Hyperlink Command="{Binding GoToMasterParameterCommand}">
         Masterparameter
    </Hyperlink>
</ListView>

<DataGrid Name="m_DataGrid" 
              ItemsSource="{Binding Path=Parameters}" 
              SelectedItem="{Binding SelectedParameter}" 
              SelectionMode="Single" 
              AutoGenerateColumns="False" 
              TargetUpdated="m_ParameterDataGrid_TargetUpdated">
        <DataGrid.Columns>
            <DataGridTextColumn 
                Header="ID" 
                Binding="{Binding Id}" 
                IsReadOnly="True"/>
            <DataGridTextColumn 
                Header="Value" 
                Binding="{Binding Value.CurrentInternalValue, NotifyOnTargetUpdated=True}"
        </DataGrid.Columns>
    </DataGrid>

internal void GoToMasterParameter()
{
    string parentId = GetParentId(this.SelectedParameter);
    this.SelectedParameter = this.Parameters.Single(item => item.Id == parentId);
}

【问题讨论】:

    标签: c# wpf data-binding wpfdatagrid


    【解决方案1】:

    您遇到的问题是选定的行/单元格没有聚焦,因为焦点仍在您的 listView 项目中。您可以做的是在 xaml 中设置 DataGridCell 元素的样式。下面是一小段代码来证明这一点:

    <Window.Resources>
        <Style TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="Red"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <DataGrid ItemsSource="{Binding Tests}" 
                  SelectedItem="{Binding GridSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                  SelectedIndex="{Binding SelectedGridIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    
    </DataGrid>
        <Button Command="{Binding ChangeSelectedItemCommand}" 
                Content="Change Grid Selected item" 
                Grid.Column="1" 
                VerticalAlignment="Top"/>
    </Grid>
    

    这里是 viewModel 部分:

    public class MainWindowViewModel : INotifyPropertyChanged
    {
        #region Private members
    
        private List<TestClass> _tests;
        private TestClass _gridSelectedItem;
        private ICommand _changeSelectedItemCommand;
        private int _selectedGridIndex;
        #endregion
    
        #region Constructor
    
        public MainWindowViewModel()
        {
            Tests = new List<TestClass>();
            for (int i = 0; i < 25; i++)
            {
                TestClass testClass= new TestClass {Name = "Name " + i, Title = "Title" + i};
                Tests.Add(testClass);
            }
        }
    
        #endregion
    
        #region Public properties
        public List<TestClass> Tests
        {
            get { return _tests; }
            set
            {
                _tests = value;
                OnPropertyChanged("Tests");
            }
        }
    
        public TestClass GridSelectedItem
        {
            get { return _gridSelectedItem; }
            set
            {
                _gridSelectedItem = value;
                OnPropertyChanged("GridSelectedItem");
            }
        }
    
        public int SelectedGridIndex
        {
            get { return _selectedGridIndex; }
            set
            {
                _selectedGridIndex = value;
                OnPropertyChanged("SelectedGridIndex");
            }
        }
    
        #endregion
    
        public ICommand ChangeSelectedItemCommand
        {
            get { return _changeSelectedItemCommand ?? (_changeSelectedItemCommand = new  SimpleCommand(p => ChangeSelectedGridItem())); }
        }
    
        private void ChangeSelectedGridItem()
        {
            SelectedGridIndex++;
        }
    
        #region INotifyPropertyChanged
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
    

    演示对象类:

    public class TestClass
    {
        public string Title { get; set; }
        public string Name { get; set; }
    }
    

    还有一些命令类:

    public class SimpleCommand : ICommand
    {
    
        private readonly Predicate<object> _canExecuteDelegate;
    
        private readonly Action<object> _executeDelegate;
    
        #region Constructors
    
        public SimpleCommand(Action<object> execute)
            : this(execute, null)
        {
        }
    
        public SimpleCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
            {
                throw new ArgumentNullException("execute");
            }
    
            _executeDelegate = execute;
            _canExecuteDelegate = canExecute;
        }
    
        #endregion // Constructors
    
        #region ICommand Members
    
        public virtual bool CanExecute(object parameter)
        {
            return _canExecuteDelegate == null || _canExecuteDelegate(parameter);
        }
    
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
    
        public void Execute(object parameter)
        {
            _executeDelegate(parameter);
        }
    
        #endregion
    }
    

    确保添加 View 的 DataContext 以便它了解您的 ViewModel:

     public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
    

    我希望这可以帮助您获得想要的效果。

    【讨论】:

    • 我想我错过了一些东西。这个 sn-p 似乎根本没有操纵焦点逻辑。我做了一个非常相似的方法。当我按下编辑我的 SelectedItem 属性的链接时,数据绑定会立即更新数据网格。所以我希望有可能使用数据绑定设置 FocusedItem
    • 此 sn-p 影响所选项目的背景。您可以仅更改背景颜色并将焦点保持在单击的项目上,或者获取真实的 DataGridCell 或 DataGridRow 并将其传递给转换器,您可以在其中设置真实 GUI 对象的 .Focus() 属性。这会将焦点从列表视图项移动到 DataGridRow/Cell