如何根据条件在DataGrid的单个单元格中制作多色 [英] How to make multicolor in a single cell of DataGrid based on condition
问题描述
您好,
我需要根据WPF数据网格中的单元格值在单个单元格中进行多色处理。
例如:
我有一个标题为InitialNames的列,另一列标题为Available
假设它包含例如以下内容:
InitialNames
ABC / BD
BVF / GFD / YA
BD
Avaiable
0/1
0/0/0
1
一行中两列的substring.count始终是相同的。
我需要的是基于/对单元格可用进行子串,如果值为1,则InitialNames列中相同索引的颜色将为红色。
我知道如何使用TextBlock.Inlines在代码中执行此操作,但我不知道如何使用new替换datagrid单元格中的结果InitialNames内联彩色字符串。
最简单的是使用转换器,我有一个颜色转换器,用于根据对象中的值更改2个单元格的颜色绑定到行。
您将转换器添加到资源然后
< Page.Resources >
< con:StatusToColorConverter x:键 = StatusToColorConverter / >
< style x:key = RowColorConverted targettype = {x:Type TextBlock} xmlns:x = #unknown >
< setter property = 背景 值 = {Binding StatusCode,Converter = {StaticResource StatusToColorConverter}} / >
< / style >
然后找到你想要的元素并使用这个风格
< DataGridTextColumn 标题 = 职位名称 宽度 = 2 * 绑定 = {Binding HdrJobTitleName} ElementStyle = {StaticResource RowColorConverted} / >
< DataGridTextColumn 标题 = 状态 宽度 < span class =code-keyword> = 1.75 * 绑定 = {Binding StatusDesc} x:名称 = StatusCol ElementStyle = {StaticResource RowColorConverted} >
这是我的价值转换器代码。
public class StatusToColorConverter:IValueConverter
{
public object 转换( object value ,输入targetType, object 参数,System.Globalization.CultureInfo文化)
{
SolidColorBrush rtn = null ;
string input = value as string ;
switch (输入)
{
case MMGlobal.NewStatusCode:
rtn = new SolidColorBrush(Colors.LawnGreen);
break ;
case MMGlobal.ErrorStatusCode:
rtn = new SolidColorBrush(Colors.Red) ;
break ;
case MMGlobal.AwaitingStatusCode:
rtn = new SolidColorBrush(Colors.Yellow) ;
break ;
case MMGlobal.CompleteStatusCode:
rtn = new SolidColorBrush(Colors.Gray) ;
break ;
case MMGlobal.ProcessStatusCode:
rtn = new SolidColorBrush(Colors.Lavender) ;
break ;
默认:
rtn = new SolidColorBrush(Colors.GhostWhite);
break ;
}
return rtn;
}
public object ConvertBack( object value ,键入targetType, object 参数,System.Globalization。 CultureInfo culture)
{
throw new NotImplementedException();
}
}
感谢您的回复
your b建议将改变单元格的颜色,但我想在单个单元格中使用多色。
下表将使其更容易理解:
如果可用栏如下:
可用
0/1
0/0/0
1
1/0/1
0/0
InitialName列如下:
InitialNames
ABC / BD
BVF / GFD / YA
BM
YVD / LKL / DDS
HGT / FDS
注意:它不是粗体,而是红色,但我不知道如何在我的回复中把它变成红色。
唯一(我能想到的)方法是以不同的颜色(基于两个独立的值)拥有可变数量的文本列是扩展TextBlock
contro l自我构建其内容。这就是我所做的。
使用 System.Windows;
使用 System.Windows.Controls;
使用 System.Windows.Documents;
使用 System.Windows.Media;
命名空间 WpfApplication3
{
public class NameAvailableTextBlock:TextBlock
{
public string InitialName
{
get { return (串跨度>)的GetValue(InitialNameProperty); }
set {SetValue(InitialNameProperty, value ); }
}
// 使用DependencyProperty作为Name的后备存储。这样可以实现动画,样式,装订等......
public static readonly DependencyProperty InitialNameProperty =
DependencyProperty.Register( InitialName, typeof ( string ), typeof (NameAvailableTextBlock), new PropertyMetadata( string .Empty,NameAvailableChanged));
public string 可用
{
get { return ( string )GetValue(AvailableProperty) ; }
set {SetValue(AvailableProperty, value ); }
}
// 使用DependencyProperty作为可用的后备存储。这样可以实现动画,样式,装订等......
public static readonly DependencyProperty AvailableProperty =
DependencyProperty.Register( 可用, typeof ( string ), typeof (NameAvailableTextBlock), new PropertyMetadata( string .Empty,NameAvailableChanged));
private static void NameAvailableChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
((NameAvailableTextBlock)d).DoNameAvailableChanged();
}
private void DoNameAvailableChanged()
{
Inlines.Clear();
// 检查InitialName或Available == null
string [] names = InitialName.Split(' /');
string [] avail = Available.Split(' / 跨度>);
if (names.Length!= available.Length)
return ; // 只是挽救,直到我们想看到的数据
for ( int i = 0 ; i < names.Length; ++ i)
{
if (i > 0 )
{
Inlines.Add( new 运行( /));
}
var run = new 运行(names [i]);
Inlines.Add(run);
if (avail [i] .Trim()== 1)
{
run.Foreground = Brushes.Red;
}
}
}
}
}
和
< pre lang =xml> < 窗口 x:Class = WpfApplication3.MainWindow
xmlns = http://schemas.microsoft。 com / winfx / 2006 / xaml / presentation
xmlns:x = http://schemas.microsoft.com/winfx/2006/xaml可用 = {Binding Available} / >
xmlns:local = clr-namespace:WpfApplication3
< span class =code-attribute> 标题 = MainWindow
高度 = 350
< span class =code-attribute> 宽度 = 525 >
< 网格 > ;
< local:NameAvailableTextBlock 宽度 = 400
高度 = 200
InitialName = {Binding InitialNames}
< / Grid >
< / Window >
在MainWindow.xaml.cs中设置DummyDataContext:
使用 System.Windows;public partial class MainWindow:Window
命名空间 WpfApplication3
{
/// < 摘要 >
/// MainWindow.xaml $ b的交互逻辑$ b /// < < span class =code-summarycomment> / summary >
{
public class DummyDataContext
{
public string InitialNames { get { return YVD / LKL / DDS; }
public string 可用{ get { return 1/0/1 跨度>; }
}
public MainWindow()
{
InitializeComponent();
DataContext = new DummyDataContext();
}
}
}
用于DataGrid
,只需将local:NameAvailableTextBlock
放入网格列的模板中。
(一个完整的FlowDocument
可能矫枉过正!)
Hello,
I need to make a multicolor in a single cell based on cell value in WPF datagrid.
For example:
I have a column which header is "InitialNames" and another column with a header "Available"
Let's say that it contains for example the following:
InitialNames
ABC/BD
BVF/GFD/YA
BD
Avaiable
0/1
0/0/0
1
It is all the time the substring.count for both columns in one row are the same.
What I need is that to substring the cell "available" based on "/" and if the value is 1 then the color of the same index in InitialNames column will be red.
I know how to do it in code using TextBlock.Inlines but I don't know how to replace the result in the datagrid cell "InitialNames" with the new inlines colored string.
The simplest is to use a converter, I have a color converter that I use to change the colors of 2 cells based on values in the object bound to the row.
You add the converter to the resources and then
<Page.Resources> <con:StatusToColorConverter x:Key="StatusToColorConverter"/> <style x:key="RowColorConverted" targettype="{x:Type TextBlock}" xmlns:x="#unknown"> <setter property="Background" value="{Binding StatusCode, Converter={StaticResource StatusToColorConverter}}" /> </style>
and then find the element you want and use the style
<DataGridTextColumn Header="Job Title Name" Width="2*" Binding="{Binding HdrJobTitleName}" ElementStyle="{StaticResource RowColorConverted}"/> <DataGridTextColumn Header="Status" Width="1.75*" Binding="{Binding StatusDesc}" x:Name="StatusCol" ElementStyle="{StaticResource RowColorConverted}">
This is my value converter code.
public class StatusToColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { SolidColorBrush rtn = null; string input = value as string; switch (input) { case MMGlobal.NewStatusCode: rtn = new SolidColorBrush(Colors.LawnGreen); break; case MMGlobal.ErrorStatusCode: rtn = new SolidColorBrush(Colors.Red); break; case MMGlobal.AwaitingStatusCode: rtn = new SolidColorBrush(Colors.Yellow); break; case MMGlobal.CompleteStatusCode: rtn = new SolidColorBrush(Colors.Gray); break; case MMGlobal.ProcessStatusCode: rtn = new SolidColorBrush(Colors.Lavender); break; default: rtn = new SolidColorBrush(Colors.GhostWhite); break; } return rtn; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }
Thank you for your reply
your suggestion will change the color for the cell but I want to use multicolor in single cell.
the following table will make it easier to understand:
If available column as below:
Available
0/1
0/0/0
1
1/0/1
0/0
The InitialName column will be as below:
InitialNames
ABC/BD
BVF/GFD/YA
BM
YVD/LKL/DDS
HGT/FDS
note: instead of bold, it will be red color but I don't know how to make it red in my reply.
The only (that I can think of) way to have a variable number of pieces of a text column in different colors (based on two independent values) is to extend theTextBlock
control to self-construct its content. Here's what I've done.
using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; namespace WpfApplication3 { public class NameAvailableTextBlock : TextBlock { public string InitialName { get { return (string)GetValue(InitialNameProperty); } set { SetValue(InitialNameProperty, value); } } // Using a DependencyProperty as the backing store for Name. This enables animation, styling, binding, etc... public static readonly DependencyProperty InitialNameProperty = DependencyProperty.Register("InitialName", typeof(string), typeof(NameAvailableTextBlock), new PropertyMetadata(string.Empty, NameAvailableChanged)); public string Available { get { return (string)GetValue(AvailableProperty); } set { SetValue(AvailableProperty, value); } } // Using a DependencyProperty as the backing store for Available. This enables animation, styling, binding, etc... public static readonly DependencyProperty AvailableProperty = DependencyProperty.Register("Available", typeof(string), typeof(NameAvailableTextBlock), new PropertyMetadata(string.Empty, NameAvailableChanged)); private static void NameAvailableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((NameAvailableTextBlock)d).DoNameAvailableChanged(); } private void DoNameAvailableChanged() { Inlines.Clear(); // check for either InitialName or Available == null string[] names = InitialName.Split('/'); string[] avail = Available.Split('/'); if (names.Length != available.Length) return; // just bail-out until the data is what we want to see for (int i = 0; i < names.Length; ++i) { if (i > 0) { Inlines.Add(new Run("/")); } var run = new Run(names[i]); Inlines.Add(run); if (avail[i].Trim() == "1") { run.Foreground = Brushes.Red; } } } } }
and
<Window x:Class="WpfApplication3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication3" Title="MainWindow" Height="350" Width="525"> <Grid> <local:NameAvailableTextBlock Width="400" Height="200" InitialName="{Binding InitialNames}" Available="{Binding Available}" /> </Grid> </Window>
With a DummyDataContext set in MainWindow.xaml.cs:
using System.Windows; namespace WpfApplication3 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public class DummyDataContext { public string InitialNames { get { return "YVD/LKL/DDS"; } } public string Available { get { return "1/0/1"; } } } public MainWindow() { InitializeComponent(); DataContext = new DummyDataContext(); } } }
For use in aDataGrid
, just put thelocal:NameAvailableTextBlock
in the template for the column of the grid.
(A fullFlowDocument
probably would be overkill!)
这篇关于如何根据条件在DataGrid的单个单元格中制作多色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!