none
在silverlight里面更改datagrid选定行的颜色 RRS feed

  • 问题

  • 为这个问题郁闷好久了!

    问题如下:
    有一个datagrid,里面有多行内容。另外有一个button,选中datagrid的一行或者多行,然后点击button,都会把选中的行的背景色改成需要的颜色。

    请问高手怎么实现?要考虑datagrid滚动行的问题。


    本人新手,高手解答时请贴出相关代码! 谢谢先啊!
    • 已编辑 ascap 2010年3月9日 9:31
    2010年2月4日 8:31

答案

  • 恐怕你需要 重新设计 DataGridRow的Style. 主要需要设计Template的VisualStateManager.
    DataGrid默认有多种VisualState,及时选中的也有多种,比如NormalSelected, MouseOverSelected, UnfocusedSelected,都需要重定义.
    当前的Style是这样定义的:

    <Style TargetType="local:DataGridRow">
            <Setter Property="IsTabStop" Value="False" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:DataGridRow">
                        <localprimitives:DataGridFrozenGrid Name="Root">
                            <vsm:VisualStateManager.VisualStateGroups>
                                <vsm:VisualStateGroup x:Name="CommonStates">
                                    <vsm:VisualState x:Name="Normal"/>
                                <vsm:VisualState x:Name="NormalAlternatingRow">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="0"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To=".5"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="NormalSelected">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="MouseOverSelected">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="UnfocusedSelected">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Fill).Color" To="#FFE1E7EC"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                                <vsm:VisualStateGroup x:Name="ValidationStates">
                                    <vsm:VisualState x:Name="Valid"/>
                                    <vsm:VisualState x:Name="Invalid">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <DoubleAnimation Storyboard.TargetName="InvalidVisualElement" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                            </vsm:VisualStateManager.VisualStateGroups>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
    
                            <Grid.Resources>
                                <Storyboard x:Key="DetailsVisibleTransition">
                                    <DoubleAnimation Storyboard.TargetName="DetailsPresenter" Storyboard.TargetProperty="ContentHeight" Duration="00:00:0.1" />
                                </Storyboard>
                            </Grid.Resources>
                                
                            <Rectangle x:Name="BackgroundRectangle" Grid.RowSpan="2" Grid.ColumnSpan="2" Opacity="0" Fill="#FFBADDE9"/>
                            <Rectangle x:Name="InvalidVisualElement" Grid.RowSpan="2" Grid.ColumnSpan="2" Opacity="0" Fill="#FFF7D8DB"/>
    
                            <localprimitives:DataGridRowHeader Grid.RowSpan="3" Name="RowHeader" localprimitives:DataGridFrozenGrid.IsFrozen="True" />
                            <localprimitives:DataGridCellsPresenter Grid.Column="1" Name="CellsPresenter" localprimitives:DataGridFrozenGrid.IsFrozen="True" />
                            <localprimitives:DataGridDetailsPresenter Grid.Row="1" Grid.Column="1" Name="DetailsPresenter" />
                            <Rectangle Grid.Row="2" Grid.Column="1" Name="BottomGridLine" HorizontalAlignment="Stretch" Height="1" />
                        </localprimitives:DataGridFrozenGrid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    你可以根据这个进行适当的修改来符合你的要求,比如增加对(Fill).Color的animation. 建议下个Blend来做这个.
    然后就可以把DataGrid的Style设成你自己的这个了.
    2010年2月9日 0:09
  • 试试看这个,这是个完整的例子:

     <Grid x:Name="LayoutRoot">
    <data:DataGrid IsReadOnly="True" 
                   x:Name="dataGrid" LoadingRow="OnLoadingRow" ItemsSource="{Binding}"  AutoGenerateColumns="False">
                <data:DataGrid.Columns>
                    <data:DataGridTemplateColumn Header="Change">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Change"  Click="OnAdjustmentClick"/>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                    <data:DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                </data:DataGrid.Columns>
                    
            </data:DataGrid>
      </Grid>


    public class TestObject : INotifyPropertyChanged
        {
    
            public string Name { get; set; }
    
            private Brush _brush;
    
            public Brush Brush
            {
                get { return _brush; }
                set { _brush = value;
     OnPropertyChanged("Brush");}
            }
    
            #region INotifyPropertyChanged 成员
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion
        }


     public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
                Loaded += new RoutedEventHandler(OnLoaded);
            }
    
            private void OnLoaded(object sender, RoutedEventArgs e)
            {
                List<TestObject> list = new List<TestObject>();
                for (int i = 0; i < 100; i++)
                {
                    list.Add(new TestObject() { Name = i.ToString(), Brush = new SolidColorBrush(Colors.White) });
                }
                this.DataContext = list;
            }
    
            private static List<UIElement> children = new List<UIElement>();
            private static void GetChildrenWithParentRec(UIElement parent, Type targetType, object dataContext)
            {
                int count = VisualTreeHelper.GetChildrenCount(parent);
    
                if (count > 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i);
                        if (VisualTreeHelper.GetParent(child).GetType() == targetType
                            && (child as FrameworkElement) != null
                            && (child as FrameworkElement).DataContext == dataContext)
                        {
                            children.Add(child);
                        }
                        GetChildrenWithParentRec(child, targetType, dataContext);
                    }
                }
            }
    
            private void ChangeBackground(object dataContext, Brush brush)
            {
                children = new List<UIElement>();
                GetChildrenWithParentRec(dataGrid, typeof(DataGridRow), dataContext);
                Grid grid;
                for (int i = 0; i < children.Count; i++)
                {
                    grid = (children[i] as Grid);
                    grid.Background = brush;
                }
            }
    
    
            private void OnAdjustmentClick(object sender, RoutedEventArgs e)
            {
                object dataContext = (sender as FrameworkElement).DataContext;
                TestObject textObject = dataContext as TestObject;
                textObject.Brush = new SolidColorBrush(Colors.Red);
                ChangeBackground(textObject, textObject.Brush);
             
            }
    
            private void OnLoadingRow(object sender, DataGridRowEventArgs e)
            {
                e.Row.SetBinding(BackgroundProperty, GetBinding(e.Row));
            }
    
    
    
            private Binding GetBinding(FrameworkElement row)
            {
                Binding binding = new Binding("Brush");
                binding.Mode = BindingMode.OneWay;
                binding.Source = row.DataContext;
                return binding;
            }
    
    
        }
    • 已标记为答案 ascap 2010年3月12日 4:33
    2010年3月11日 4:55

全部回复

  • 恐怕你需要 重新设计 DataGridRow的Style. 主要需要设计Template的VisualStateManager.
    DataGrid默认有多种VisualState,及时选中的也有多种,比如NormalSelected, MouseOverSelected, UnfocusedSelected,都需要重定义.
    当前的Style是这样定义的:

    <Style TargetType="local:DataGridRow">
            <Setter Property="IsTabStop" Value="False" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:DataGridRow">
                        <localprimitives:DataGridFrozenGrid Name="Root">
                            <vsm:VisualStateManager.VisualStateGroups>
                                <vsm:VisualStateGroup x:Name="CommonStates">
                                    <vsm:VisualState x:Name="Normal"/>
                                <vsm:VisualState x:Name="NormalAlternatingRow">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="0"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To=".5"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="NormalSelected">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="MouseOverSelected">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="UnfocusedSelected">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                            <ColorAnimation Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Fill).Color" To="#FFE1E7EC"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                                <vsm:VisualStateGroup x:Name="ValidationStates">
                                    <vsm:VisualState x:Name="Valid"/>
                                    <vsm:VisualState x:Name="Invalid">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <DoubleAnimation Storyboard.TargetName="InvalidVisualElement" Storyboard.TargetProperty="Opacity" Duration="0" To="1"/>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                            </vsm:VisualStateManager.VisualStateGroups>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
    
                            <Grid.Resources>
                                <Storyboard x:Key="DetailsVisibleTransition">
                                    <DoubleAnimation Storyboard.TargetName="DetailsPresenter" Storyboard.TargetProperty="ContentHeight" Duration="00:00:0.1" />
                                </Storyboard>
                            </Grid.Resources>
                                
                            <Rectangle x:Name="BackgroundRectangle" Grid.RowSpan="2" Grid.ColumnSpan="2" Opacity="0" Fill="#FFBADDE9"/>
                            <Rectangle x:Name="InvalidVisualElement" Grid.RowSpan="2" Grid.ColumnSpan="2" Opacity="0" Fill="#FFF7D8DB"/>
    
                            <localprimitives:DataGridRowHeader Grid.RowSpan="3" Name="RowHeader" localprimitives:DataGridFrozenGrid.IsFrozen="True" />
                            <localprimitives:DataGridCellsPresenter Grid.Column="1" Name="CellsPresenter" localprimitives:DataGridFrozenGrid.IsFrozen="True" />
                            <localprimitives:DataGridDetailsPresenter Grid.Row="1" Grid.Column="1" Name="DetailsPresenter" />
                            <Rectangle Grid.Row="2" Grid.Column="1" Name="BottomGridLine" HorizontalAlignment="Stretch" Height="1" />
                        </localprimitives:DataGridFrozenGrid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    你可以根据这个进行适当的修改来符合你的要求,比如增加对(Fill).Color的animation. 建议下个Blend来做这个.
    然后就可以把DataGrid的Style设成你自己的这个了.
    2010年2月9日 0:09
  • 谢谢版主!
    2010年2月11日 7:19
  • 目前我是這樣解決的:
    点击按鈕時可以調用類似這樣的代碼,改變行的顏色

    private void OnClick(){
     children = new List<UIElement>();
                    GetChildrenWithParentRec(dgResult, typeof(DataGridRow), item.EmployeeGuid);
                    Grid grid;
                    for (int i = 0; i < children.Count; i++)
                    {
                        grid = (children[i] as Grid);
                        AttendanceReportItem reportItem = grid.DataContext as AttendanceReportItem;
                        grid.Background = BackgroundConverter.GetBackground(reportItem.IsNormalState);
                    }
    }
    
    
     private static List<UIElement> children = new List<UIElement>();
            private static void GetChildrenWithParentRec(UIElement parent, Type targetType, string employeeGuid)
            {
                int count = VisualTreeHelper.GetChildrenCount(parent);
    
                if (count > 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i);
                        if (VisualTreeHelper.GetParent(child).GetType() == targetType
                            && (child as FrameworkElement) != null
                            && ((child as FrameworkElement).DataContext as AttendanceReportItem).EmployeeGuid == employeeGuid)
                        {
                            children.Add(child);
                        }
                        GetChildrenWithParentRec(child, targetType, employeeGuid);
                    }
                }
            }
    至於滾動行的問題,就需要在LoadingRow事件中綁定行的背景
      private void OnLoadingRow(object sender, DataGridRowEventArgs e) { e.Row.SetBinding(BackgroundProperty, GetBinding(e.Row)); }
    
            private Binding GetBinding(FrameworkElement row)
            {
                Binding binding = new Binding("IsNormalState");
                binding.Mode = BindingMode.OneWay;
                binding.Converter = new BackgroundConverter();
                binding.Source = row.DataContext;
                return binding;
            }

    2010年2月23日 4:11
  • 不明,你好。在我引用你的代码的时候发现这样的问题我没理解。item.EmployeeGuid怎么得到的?
    还有BackgroundConverter,好像没有这样的系统函数,是你自己实现的吧,能麻烦把代码贴出来吗?

    再次谢谢你了!

    2010年3月2日 9:08
  • 不明,你好。在我引用你的代码的时候发现这样的问题我没理解。item.EmployeeGuid怎么得到的?
    还有BackgroundConverter,好像没有这样的系统函数,是你自己实现的吧,能麻烦把代码贴出来吗?

    再次谢谢你了!


    在DataGrid 中放一個包含按鈕的模版列
                    <data:DataGridTemplateColumn Header="調整">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button                                           ToolTipService.ToolTip="調整考勤記錄"     Click="OnAdjustmentClick"/>
                              </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>



    處理點擊事件(sender 就是那個Button,Button.DataContext就是Button所在那一行的數據)
        private void OnAdjustmentClick(object sender, RoutedEventArgs e)
            {
                FrameworkElement element = sender as FrameworkElement;
                if (element == null) { return; }
                AttendanceReportItem item = element.DataContext as AttendanceReportItem;
    string employeeGuid=item.EmployeeGuid;
    }



    BackgroundConverter是自己實現IValueConverter的類,綁定IsNormalState這個字段,當這個字段為False時返回半透明的紅色
      public class BackgroundConverter : IValueConverter
        {
            private static Brush ErrorBackground = new SolidColorBrush(Color.FromArgb(25, 255, 0, 0));
            #region IValueConverter 成员
            public static Brush GetBackground(bool value)
            {
                return value ? null : ErrorBackground;
            }
    
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                bool b = (bool)value;
                return GetBackground(b);
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                return value;
            }
    
            #endregion
        }
    2010年3月4日 3:07
  • TFSoft 给你一个可以直接运行的完整例子,如下:

    .xaml文件内容

    <UserControl x:Class="Test1.MainPage"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 mc:Ignorable="d"
                 d:DesignWidth="640"
                 d:DesignHeight="480"
                 xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"
                 xmlns:my="clr-namespace:Test1">
        <UserControl.Resources>
            <my:CBgColorList x:Key="BgColorList"></my:CBgColorList>
            <my:CStudentList x:Key="StudentList"></my:CStudentList>

            <DataTemplate x:Key="DtpMark">
                <Grid Width="120">
                    <ComboBox SelectionChanged="SetBgColor_SelectionChanged"
                              ItemsSource="{Binding Path=BgColorList,Source={StaticResource BgColorList},Mode=OneWay}">
                        <ComboBox.ItemTemplate>
                            <DataTemplate>
                                <Grid>
                                    <StackPanel Orientation="Horizontal">
                                        <Border Width="10"
                                                Height="10"
                                                BorderThickness="1"
                                                BorderBrush="Silver">
                                            <Rectangle Fill="{Binding Path=ColorValue,Mode=OneWay}"></Rectangle>
                                        </Border>
                                        <TextBlock Text="{Binding Path=ColorName,Mode=OneWay}"
                                                   Foreground="Black"></TextBlock>
                                    </StackPanel>
                                </Grid>
                            </DataTemplate>
                        </ComboBox.ItemTemplate>
                    </ComboBox>
                </Grid>
            </DataTemplate>
            <DataTemplate x:Key="DtpId">
                <Grid Background="{Binding Path=BgColor,Mode=OneWay}">
                    <TextBlock Width="40"
                               Text="{Binding Path=Id,Mode=OneWay}"></TextBlock>
                </Grid>
            </DataTemplate>
            <DataTemplate x:Key="DtpName">
                <Grid  Background="{Binding Path=BgColor,Mode=OneWay}">
                    <TextBlock Width="100"
                               Text="{Binding Path=Name,Mode=OneWay}"></TextBlock>
                </Grid>
            </DataTemplate>
            <DataTemplate x:Key="DtpChinese">
                <Grid  Background="{Binding Path=BgColor,Mode=OneWay}">
                    <TextBlock Width="80"
                               Text="{Binding Path=Chinese,Mode=OneWay}"></TextBlock>
                </Grid>
            </DataTemplate>
            <DataTemplate x:Key="DtpMath">
                <Grid  Background="{Binding Path=BgColor,Mode=OneWay}">
                    <TextBlock Width="80"
                               Text="{Binding Path=Math,Mode=OneWay}"></TextBlock>
                </Grid>
            </DataTemplate >
            <DataTemplate x:Key="DtpTotal">
                <Grid  Background="{Binding Path=BgColor,Mode=OneWay}">
                    <TextBlock Width="80"
                               Text="{Binding Path=Total,Mode=OneWay}"></TextBlock>
                </Grid>
            </DataTemplate>
            <DataTemplate x:Key="DtpAverage">
                <Grid  Background="{Binding Path=BgColor,Mode=OneWay}">
                    <TextBlock Width="80"
                               Text="{Binding Path=Average,Mode=OneWay}"></TextBlock>
                </Grid>
            </DataTemplate>
        </UserControl.Resources>
        <Grid x:Name="LayoutRoot">
            <StackPanel Orientation="Vertical"
                        VerticalAlignment="Center"
                        HorizontalAlignment="Center">
                <TextBlock Text="Students List"
                           Width="600"
                           TextAlignment="Center"></TextBlock>
                <data:DataGrid x:Name="DgrStudentList"
                               Width="600"
                               Height="300"
                               GridLinesVisibility="All"
                               ColumnHeaderHeight="24"
                               RowHeight="20"
                               HorizontalScrollBarVisibility="Visible"
                               VerticalScrollBarVisibility="Visible"
                               AutoGenerateColumns="False"
                               ItemsSource="{Binding Path=StudentList,Source={StaticResource StudentList},Mode=OneWay}">
                    <data:DataGrid.Columns>
                        <data:DataGridTemplateColumn Header="Mark"
                                                     CellTemplate="{StaticResource DtpMark}"></data:DataGridTemplateColumn>
                        <data:DataGridTemplateColumn Header="Id"
                                                     CellTemplate="{StaticResource DtpId}"></data:DataGridTemplateColumn>
                        <data:DataGridTemplateColumn Header="Name"
                                                     CellTemplate="{StaticResource DtpName}"></data:DataGridTemplateColumn>
                        <data:DataGridTemplateColumn Header="Chinese"
                                                     CellTemplate="{StaticResource DtpChinese}"></data:DataGridTemplateColumn>
                        <data:DataGridTemplateColumn Header="Math"
                                                     CellTemplate="{StaticResource DtpMath}"></data:DataGridTemplateColumn>
                        <data:DataGridTemplateColumn Header="Total"
                                                     CellTemplate="{StaticResource DtpTotal}"></data:DataGridTemplateColumn>
                        <data:DataGridTemplateColumn Header="Average"
                                                     CellTemplate="{StaticResource DtpAverage}"></data:DataGridTemplateColumn>
                    </data:DataGrid.Columns>
                </data:DataGrid>
            </StackPanel>
        </Grid>
    </UserControl>


    .cs 文件内容

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Windows.Controls;
    using System.Windows.Media;

    namespace Test1 {

        public partial class MainPage : UserControl {
            public MainPage() {
                InitializeComponent();
            }
            private void SetBgColor_SelectionChanged(object sender, SelectionChangedEventArgs e) {
                var StudentItem = DgrStudentList.SelectedItem as CStudentItem;
                var BgColorItem = (sender as ComboBox).SelectedItem as CBgColorItem;
                StudentItem.BgColor = BgColorItem.ColorValue;
            }
        }

        public class CBgColorList {
            public CBgColorList() {
                BgColorList = new List<CBgColorItem>();
                BgColorList.Add(new CBgColorItem("Transparent", new SolidColorBrush(Colors.Transparent)));
                BgColorList.Add(new CBgColorItem("Red", new SolidColorBrush(Colors.Red)));
                BgColorList.Add(new CBgColorItem("Green", new SolidColorBrush(Colors.Green)));
                BgColorList.Add(new CBgColorItem("Blue", new SolidColorBrush(Colors.Blue)));
            }
            public List<CBgColorItem> BgColorList { get; set; }
        }
        public class CBgColorItem {
            public CBgColorItem(String TheColorName, SolidColorBrush TheColorValue) {
                ColorName = TheColorName; ColorValue = TheColorValue;
            }
            public override string ToString() { return ColorName; }
            public String ColorName { get; set; }
            public SolidColorBrush ColorValue { get; set; }
        }

        public class CStudentList {
            public CStudentList() {
                StudentList = new List<CStudentItem>();
                StudentList.Add(new CStudentItem("01", "Zhao", 80, 90));
                StudentList.Add(new CStudentItem("02", "Quan", 70, 92));
                StudentList.Add(new CStudentItem("03", "Sun", 50, 40));
                StudentList.Add(new CStudentItem("04", "Li", 80, 90));
                StudentList.Add(new CStudentItem("05", "Zou", 70, 92));
                StudentList.Add(new CStudentItem("06", "Wu", 50, 40));
                StudentList.Add(new CStudentItem("07", "Zheng", 80, 90));
                StudentList.Add(new CStudentItem("08", "Wang", 70, 92));
                StudentList.Add(new CStudentItem("09", "Feng", 50, 40));
                StudentList.Add(new CStudentItem("10", "Chen", 80, 90));
                StudentList.Add(new CStudentItem("11", "Zhe", 70, 92));
                StudentList.Add(new CStudentItem("12", "Wei", 50, 40));
            }
            public List<CStudentItem> StudentList { get; set; }
        }
        public class CStudentItem : INotifyPropertyChanged {
            public CStudentItem(String TheId, String TheName, Double TheChinese, Double TheMath) {
                Id = TheId; Name = TheName; Chinese = TheChinese; Math = TheMath;
                BgColor = new SolidColorBrush(Colors.Transparent);
            }
            private SolidColorBrush _BgColor;
            public SolidColorBrush BgColor {
                get { return _BgColor; }
                set { _BgColor = value; Notify("BgColor"); }
            }
            public String Id { get; set; }
            public String Name { get; set; }
            public Double Chinese { get; set; }
            public Double Math { get; set; }
            public Double Total { get { return Chinese + Math; } }
            public Double Average { get { return (Chinese + Math) / 2; } }
            public event PropertyChangedEventHandler PropertyChanged;
            private void Notify(String PropName) {
                if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(PropName)); }
            }
        }
    }

    • 已标记为答案 ascap 2010年3月5日 3:31
    • 取消答案标记 ascap 2010年3月9日 9:33
    2010年3月4日 6:38
  • 明,你好

    我在引用你的方法的时候发现一个问题,就是不能解决scroll up/down的问题。请明示怎么解决这个问题吗?

    谢谢了!

    2010年3月9日 9:33
  • 试试看这个,这是个完整的例子:

     <Grid x:Name="LayoutRoot">
    <data:DataGrid IsReadOnly="True" 
                   x:Name="dataGrid" LoadingRow="OnLoadingRow" ItemsSource="{Binding}"  AutoGenerateColumns="False">
                <data:DataGrid.Columns>
                    <data:DataGridTemplateColumn Header="Change">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Change"  Click="OnAdjustmentClick"/>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                    <data:DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                </data:DataGrid.Columns>
                    
            </data:DataGrid>
      </Grid>


    public class TestObject : INotifyPropertyChanged
        {
    
            public string Name { get; set; }
    
            private Brush _brush;
    
            public Brush Brush
            {
                get { return _brush; }
                set { _brush = value;
     OnPropertyChanged("Brush");}
            }
    
            #region INotifyPropertyChanged 成员
    
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion
        }


     public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
                Loaded += new RoutedEventHandler(OnLoaded);
            }
    
            private void OnLoaded(object sender, RoutedEventArgs e)
            {
                List<TestObject> list = new List<TestObject>();
                for (int i = 0; i < 100; i++)
                {
                    list.Add(new TestObject() { Name = i.ToString(), Brush = new SolidColorBrush(Colors.White) });
                }
                this.DataContext = list;
            }
    
            private static List<UIElement> children = new List<UIElement>();
            private static void GetChildrenWithParentRec(UIElement parent, Type targetType, object dataContext)
            {
                int count = VisualTreeHelper.GetChildrenCount(parent);
    
                if (count > 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i);
                        if (VisualTreeHelper.GetParent(child).GetType() == targetType
                            && (child as FrameworkElement) != null
                            && (child as FrameworkElement).DataContext == dataContext)
                        {
                            children.Add(child);
                        }
                        GetChildrenWithParentRec(child, targetType, dataContext);
                    }
                }
            }
    
            private void ChangeBackground(object dataContext, Brush brush)
            {
                children = new List<UIElement>();
                GetChildrenWithParentRec(dataGrid, typeof(DataGridRow), dataContext);
                Grid grid;
                for (int i = 0; i < children.Count; i++)
                {
                    grid = (children[i] as Grid);
                    grid.Background = brush;
                }
            }
    
    
            private void OnAdjustmentClick(object sender, RoutedEventArgs e)
            {
                object dataContext = (sender as FrameworkElement).DataContext;
                TestObject textObject = dataContext as TestObject;
                textObject.Brush = new SolidColorBrush(Colors.Red);
                ChangeBackground(textObject, textObject.Brush);
             
            }
    
            private void OnLoadingRow(object sender, DataGridRowEventArgs e)
            {
                e.Row.SetBinding(BackgroundProperty, GetBinding(e.Row));
            }
    
    
    
            private Binding GetBinding(FrameworkElement row)
            {
                Binding binding = new Binding("Brush");
                binding.Mode = BindingMode.OneWay;
                binding.Source = row.DataContext;
                return binding;
            }
    
    
        }
    • 已标记为答案 ascap 2010年3月12日 4:33
    2010年3月11日 4:55
  • 稍微改一下,加上一次改变多行的代码。

     public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
                Loaded += new RoutedEventHandler(OnLoaded);
            }
    
            private void OnLoaded(object sender, RoutedEventArgs e)
            {
                List<TestObject> list = new List<TestObject>();
                for (int i = 0; i < 100; i++)
                {
                    list.Add(new TestObject() { Name = i.ToString()});
                }
                this.DataContext = list;
            }
    
            private static List<UIElement> children = new List<UIElement>();
            private static void GetChildrenWithParentRec(UIElement parent, Type targetType, object dataContext)
            {
                int count = VisualTreeHelper.GetChildrenCount(parent);
    
                if (count > 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i);
                        if (VisualTreeHelper.GetParent(child).GetType() == targetType
                            && (child as FrameworkElement) != null
                            && (child as FrameworkElement).DataContext == dataContext)
                        {
                            children.Add(child);
                        }
                        GetChildrenWithParentRec(child, targetType, dataContext);
                    }
                }
            }
    
            private void ChangeBackground(object dataContext, Brush brush)
            {
                children = new List<UIElement>();
                GetChildrenWithParentRec(dataGrid, typeof(DataGridRow), dataContext);
                Grid grid;
                for (int i = 0; i < children.Count; i++)
                {
                    grid = (children[i] as Grid);
                    grid.Background = brush;
                }
            }
    
    
            private void OnAdjustmentClick(object sender, RoutedEventArgs e)
            {
                object dataContext = (sender as FrameworkElement).DataContext;
                TestObject textObject = dataContext as TestObject;
                textObject.Brush = new SolidColorBrush(Colors.Red);
                ChangeBackground(textObject, textObject.Brush);
             
            }
    
            private void OnLoadingRow(object sender, DataGridRowEventArgs e)
            {
                e.Row.SetBinding(BackgroundProperty, GetBinding(e.Row));
            }
    
    
    
            private Binding GetBinding(FrameworkElement row)
            {
                Binding binding = new Binding("Brush");
                binding.Mode = BindingMode.OneWay;
                binding.Source = row.DataContext;
                return binding;
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                List<TestObject> list = dataGrid.ItemsSource as List<TestObject>;
                for (int i = 0; i < 10; i++)
                {
                    list[i].Brush = new SolidColorBrush(Colors.Red);
                    ChangeBackground(list[i], list[i].Brush);
                }
            }
    
    
        }
    <data:DataGrid IsReadOnly="True" 
                   x:Name="dataGrid" LoadingRow="OnLoadingRow" ItemsSource="{Binding}"  AutoGenerateColumns="False">
                <data:DataGrid.Columns>
                    <data:DataGridTemplateColumn Header="Change">
                        <data:DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Content="Change"  Click="OnAdjustmentClick"/>
                            </DataTemplate>
                        </data:DataGridTemplateColumn.CellTemplate>
                    </data:DataGridTemplateColumn>
                    <data:DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                </data:DataGrid.Columns>
                    
            </data:DataGrid>
            <Button Height="100" Width="100" Click="Button_Click"/>
        </Grid>


    2010年3月11日 10:25
  • 谢谢不明,问题我已经解决。
    2010年3月12日 4:33