【问题标题】:c# - WPF highlight Selected Row of Datagridc# - WPF 突出显示 Datagrid 的选定行
【发布时间】:2013-06-11 04:46:29
【问题描述】:

我正在研究一个 WPF 应用程序 MVVM 模式,我必须在其中创建 TreeViewGrid 之间的某种关系。这个想法是突出显示 id 等于树节点 id 的行。

显示颜色属性

 public Brush DisplayColor
    {
        set
        {
            _displayColor = value;
            NotifyPropertyChanged("DisplayColor");
        }

        get { return _displayColor; }

    }

**Select TreeNode value.id** 



    private MessageElementViewModel _selectedMessageElement;
            public MessageElementViewModel SelectedMessageElement
            {
                set
                {
                    if (_selectedMessageElement == value) return;
                    this._selectedMessageElement = value;
                    SearchGrid(value.Id, messageFields);

                }
                get
                {
                    return this._selectedMessageElement;
                }

            }
    // search matching Id in the grid

             public void SearchGrid(int id, ObservableCollection<MessageFieldViewModel> msgField)
            {
                 if (msgField.Any())
                    DisplayColor = msgField.Last().Id == id ? Brushes.CadetBlue : Brushes.Black;
            }

XAML: Call the display color property to highlight a matching id.
DataGrid


 <DataGrid   ItemsSource="{Binding MessageFields}" Margin="4,0,380,6" Grid.Row="2" AutoGenerateColumns="False"  IsReadOnly="True"   SelectedValue="{Binding SelectedMessageField, Mode=TwoWay}"
                    RowBackground="{Binding Path=DisplayColor}">

TreeView:



 <TreeView Margin="644,137,6,6" Grid.RowSpan="2" ItemsSource="{Binding MessageElements[0].Children[0].Children,  Mode=TwoWay}"   
                  SelectedItemChanged="TreeView_OnSelectedItemChanged"
                 SelectedValuePath="Id">

Code Behind for treeview select item;



readonly MainWindowModel _mainWindowModel = new MainWindowModel();

    private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        if (_mainWindowModel != null)
            _mainWindowModel.SelectedMessageElement = (MessageElementViewModel)e.NewValue;
    }

编辑:

     <DataGrid Name="Datagrid"    ItemsSource="{Binding MessageFields}" Margin="4,0,380,6" Grid.Row="2" AutoGenerateColumns="False"  IsReadOnly="True"   SelectedValue="{Binding SelectedMessageField}"
                            AlternatingRowBackground ="{Binding Path=DisplayColor}" RowBackground="{Binding Path=DisplayColor}" Background="CadetBlue">
                    <DataGrid.Columns >
                        <DataGridTextColumn Header="ID" Binding="{Binding Id}" Width="*"  />      <!--Foreground="{Binding Path=DisplayColor}-->

                        <DataGridTextColumn Header="Code" Binding="{Binding Code}" Width="*" />
                        <DataGridTextColumn Header="Field Name" Binding="{Binding Name}" Width="*" />
                        <DataGridTextColumn Header="Position" Binding="{Binding Position}" Width="*"   />
                        <DataGridTextColumn Header="Length" Binding="{Binding Length}" Width="*"  />
         </DataGrid.Columns>
    </DataGrid> 

为什么我的显示颜色属性不适用于匹配 ID?

【问题讨论】:

  • 我没有看到您在任何地方绑定到 DisplayColor 属性。发布完整的 XAML。此外,您的搜索应该是Linq,而不是for
  • 我更新了我的原始帖子以显示 displayColor 调用。
  • @HighCore 我更新到 linq 但没有任何效果。我更新了我原来的帖子
  • 您可以使用Triggers 来实现这一点。

标签: wpf mvvm datagrid treeview


【解决方案1】:

我想我找到了解决这个问题的方法,但我讨厌它,因为我是从后面的代码中做的。如果我能在我的虚拟机中做到这一点,那就太好了。

    private void TreeView_OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {

        foreach (MessageFieldViewModel item in Datagrid.ItemsSource)
        {
            if (_mainWindowModel != null)
                _mainWindowModel.SelectedMessageElement = (MessageElementViewModel) e.NewValue;


            foreach (MessageFieldViewModel rowItem in Datagrid.ItemsSource)
            {
                var row = Datagrid.ItemContainerGenerator.ContainerFromItem(rowItem) as DataGridRow;
                if (_mainWindowModel.SelectedMessageElement != null)
                    if (rowItem.Id == _mainWindowModel.SelectedMessageElement.Id)

                        row.Background = _mainWindowModel.DisplayColor;

                     else
                    row.Background = Brushes.White;

            }
        }


    }

【讨论】:

    【解决方案2】:

    你可以简单地使用触发器

    XAML

        <DataGrid.Resources>
            <Style TargetType="{x:Type DataGridRow}">
                <Setter Property="Background" Value="Red"/><!--default color-->
                <Style.Triggers>
                    <DataTrigger Binding="{Binding DisplayColor}" Value="Black">
                        <Setter Property="Background" Value="Black"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding DisplayColor}" Value="CadetBlue">
                        <Setter Property="Background" Value="CadetBlue"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </DataGrid.Resources>
    

    建议您的Datagrid.ItemsSourceList&lt;MyClass&gt; 您的MyClass 必须包含以下Property

    public string DisplayColor //don't use Brush
    {
        set
        {
            _displayColor = value;
            NotifyPropertyChanged("DisplayColor");
        }
    
        get { return _displayColor; }
    
    }
    

    进一步解释HERE

    【讨论】:

    • 我试过了,效果很好。我同意 WiiMaxx - 样式触发器是必要的,它们会清理视图模型中的大量代码。
    猜你喜欢
    • 2015-10-31
    • 1970-01-01
    • 2013-12-20
    • 2011-10-01
    • 2023-03-29
    • 1970-01-01
    • 2011-05-27
    • 1970-01-01
    • 2015-01-18
    相关资源
    最近更新 更多