2010-09-08 5 views
9

Tôi có DataGrid ràng buộc dữ liệu với các màu nền của hàng xen kẽ. Tôi muốn tô màu một ô khác nhau dựa trên dữ liệu chứa. Tôi đã thử các giải pháp được đề xuất bởi chủ đề nàyWPF - Cách lấy ô từ DataGridRow?

http://wpf.codeplex.com/Thread/View.aspx?ThreadId=51143

Nhưng,

DataGridCellsPresenter người dẫn chương trình = GetVisualChild (hàng)

luôn trả về null.

Tôi đang sử dụng

public static T GetVisualChild<T>(Visual parent) where T : Visual 
    { 
     T child = default(T); 
     int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < numVisuals; i++) 
     { 
      Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
      child = v as T; 
      if (child == null) 
      { 
       child = GetVisualChild<T>(v); 
      } 
      if (child != null) 
      { 
       break; 
      } 
     } 
     return child; 
    } 

Nhưng VisualTreeHelper.GetChildrenCount() của một DataGridRow luôn trả về 0. Tôi đã xác minh rằng DataGridRow không phải là null và đã được dân cư với dữ liệu rồi. Bất kỳ trợ giúp được đánh giá cao.

Cảm ơn.

Trả lời

8

Điều đầu tiên trước tiên, đừng làm điều này trong mã sau. Bạn đang chiến đấu với khung làm việc theo cách này. WPF được thiết kế khác nhau; bạn phải suy nghĩ về cách mà khung làm việc muốn bạn làm mọi thứ. Trong trường hợp của WPF, đó là đánh dấu XAML + các lớp chuyển đổi.

Bạn cần hai điều để đạt được những gì bạn muốn:

  • markup XAML thích hợp để thiết lập phong cách của DataGrid
  • thực hiện Một IValueConverter để dịch các giá trị của văn bản sang màu nổi bật thích hợp.

đây đi:

XAML Trong DataGrid của bạn

Điều đầu tiên bạn muốn làm là xác định XAML cần thiết để tạo kiểu tế bào DataGrid của bạn. Nó trông giống như thế này:

<toolkit:DataGrid.CellStyle> 
     <Style TargetType="{x:Type toolkit:DataGridCell}"> 
     <Style.Setters> 
      <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text, Converter={StaticResource dataGridCellConverter}}" /> 
     </Style.Setters> 
     </Style> 
    </toolkit:DataGrid.CellStyle> 

Điều này đang làm là thiết lập một liên kết với các RelativeSource (các DataGridCell) và nói cho nó để sử dụng Content.Text của tế bào như giá trị để vượt qua các Converter (dataGridCellConverter).

IValueConverter

Điều tiếp theo bạn cần là một thực hiện IValueConverter để thực sự xác định màu sắc dựa trên văn bản của tế bào:

using System; 
using System.Globalization; 
using System.Windows.Data; 
using System.Windows.Media; 
namespace UserControls.Utility.Converters 
{ 
    public class DataGridCellConverter : IValueConverter 
    { 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) return Colors.White.ToString(); 

     if (value.ToString().ToUpper().Contains("CMS")) return "LIME"; 

     return "ORANGE"; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
    } 
} 

Ở đây, tôi chỉ tìm kiếm các văn bản "CMS" và tô màu ô nền; nếu "CMS" không tồn tại, thì nó sẽ trả về màu cam thay thế.

Chỉ định Tài

Bây giờ, bạn cần phải thêm đánh dấu trong cửa sổ của bạn/usercontrol để xác định chuyển đổi như một nguồn tài nguyên thích hợp:

<UserControl.Resources> 
    <Converters:DataGridCellConverter x:Key="dataGridCellConverter"/> 
</UserControl.Resources> 

Và rằng nên làm điều đó! Chúc may mắn.

+0

+1 - câu trả lời rất chi tiết – David

+3

'Trong trường hợp của WPF, đó là đánh dấu XAML + các lớp chuyển đổi.' - đây là nhận thức cá nhân của riêng bạn –

11

Nếu bạn biết hàng và chỉ số ô bạn muốn truy cập của bạn, sau đó đây là cách bạn có thể làm điều đó trong mã:

//here's usage 
var cell = myDataGrid.GetCell(row, columnIndex); 
if(cell != null) 
    cell.Background = Brushes.Green; 

DataGrid Extension:

public static class DataGridExtensions 
{ 
    public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int columnIndex = 0) 
    { 
     if (row == null) return null; 

     var presenter = row.FindVisualChild<DataGridCellsPresenter>(); 
     if (presenter == null) return null; 

     var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex); 
     if (cell != null) return cell; 

     // now try to bring into view and retreive the cell 
     grid.ScrollIntoView(row, grid.Columns[columnIndex]); 
     cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex); 

     return cell; 
    } 
+1

đó là câu trả lời thực sự. –

+0

Tôi đang thử một cái gì đó như thế này nhưng nó dường như không hoạt động. Bạn có thể kiểm tra chủ đề này http://stackoverflow.com/questions/32584353/wpf-control-datagrid-cell-color-change –

+1

Tốt đẹp của nó nếu bạn thêm [phương pháp] sau đây (http://stackoverflow.com/a/25229554/2470362) cho câu trả lời. –