【发布时间】:2018-09-26 19:59:38
【问题描述】:
我使用以下链接在表格中显示我的二维数据:
How to bind an 2D array bool[][] to a WPF DataGrid (one-way)?
Change DataGrid cell colour based on values
除了背景颜色没有改变(甚至没有点击转换器方法)之外,一切都在工作。谁能告诉我这是怎么回事?
下面我发布一个完整的、最小的示例。我不喜欢任何这些想法(例如,使用 DataView 绑定我的 IEnumerable>),因此请随意提出替代方法。我唯一的硬性要求是,在我的实际项目中,数据以 IEnumerable>
的形式给出代码如下:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ViewModel vm = new ViewModel();
List<Column> row1 = new List<Column>()
{
new Column(){Make = Make.Ford,OperatingStatus = OperatingStatus.Broken},
new Column(){Make = Make.Honda, OperatingStatus = OperatingStatus.Unknown}
};
List<Column> row2 = new List<Column>()
{
new Column() {Make = Make.GM, OperatingStatus = OperatingStatus.Working},
new Column() {Make = Make.Toyota, OperatingStatus = OperatingStatus.Broken}
};
List<List<Column>> data = new List<List<Column>>();
data.Add(row1);
data.Add(row2);
vm.Data = data;
DataContext = vm;
}
}
public enum OperatingStatus
{
Working = 0,
Broken = 1,
Unknown = 2
}
public enum Make
{
Ford,
Honda,
GM,
Toyota
}
public class Column
{
public Make Make { get; set; }
public OperatingStatus OperatingStatus { get; set; }
}
public class ViewModel
{
public IEnumerable<IEnumerable<Column>> Data { get; set; }
public DataView MyDataTable
{
get
{
var rows = Data.Count();
var cols = Data.First().Count();
var t = new DataTable();
for (var c = 0; c < cols; c++)
{
t.Columns.Add(new DataColumn(c.ToString()));
}
foreach (var row in Data)
{
var newRow = t.NewRow();
int c = 0;
foreach (var col in row)
{
newRow[c] = col.Make;
c++;
}
t.Rows.Add(newRow);
}
return t.DefaultView;
}
}
}
public class NameToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string input = value as string;
switch (input)
{
case "Ford":
return Brushes.LightGreen;
case "GM":
return Brushes.Red;
case "Toyota":
return Brushes.Blue;
case "Honda":
return Brushes.Yellow;
default:
return DependencyProperty.UnsetValue;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
这里是 XAML
<Window x:Class="StackOverFlowDataGridQuestion.MainWindow"
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"
xmlns:local="clr-namespace:StackOverFlowDataGridQuestion"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:NameToBrushConverter x:Key="NameToBrushConverter"/>
</Window.Resources>
<Grid>
<ScrollViewer>
<DataGrid Width="1000"
Margin="0"
HorizontalAlignment="Left"
DataContext="{Binding}"
ItemsSource="{Binding MyDataTable}" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Make}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="{Binding Make, Converter={StaticResource NameToBrushConverter}}"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</ScrollViewer>
</Grid>
在尝试了 Nik 的建议并在两个地方将 'Make' 替换为 'Row[0]' 之后,我得到了以下内容,这是进步,因为有一些颜色!如果有更多变化,我会在这里报告。
我本来希望福特广场是绿色的,本田是黄色的,通用是红色的,丰田是蓝色的。更像下面的东西(请原谅我糟糕的标记技巧)。
【问题讨论】:
-
名称是否不变而其他列不同?假设数组甚至具有可变维度(?)很久以前,我写了一些东西来处理具有一些固定列和任意数量的可变列的对象。我使用了一个视图模型,其中将固定列定义为属性,并为这些列使用了一个 observabledictionary。完全不确定这对你正在做的事情有好处,或者在任何方面都比 Nik 的建议更好。扩展对象是另一种选择。
-
安迪,我不确定我是否理解你的问题。每列代表一个具有两个属性“Make”和“OperatingStatus”的对象。但是,现在我要求只根据 Make 设置颜色。每行将具有相同数量的列。它需要可配置,以便我可以更改列数,但这不会在一次运行中发生(应用程序必须重新启动)。此外,在实际应用程序中,数据更像是 5000 行和 15 列。但同样,每一列代表相同类型的对象。感谢您的评论!
标签: wpf converter wpfdatagrid dataview