如何以紅色文本顯示DataTable中單元格的值,當它與另一個DataTable中的單元格不同時?在最終的應用程序中,表格將通過更改csv文件生成。所以我必須替換自動生成的列。我知道你需要一個DataGridTemplateColumn,將CellTemplate設置爲資源。然而,這個替換的列然後不是視覺樹的一部分,因此綁定不起作用。在紅色的數據網格上顯示數據表中的紅色已更改的文本WPF
文章How to bind to data when the DataContext is not inherited顯示實現Freezable對象的轉換器應解決此問題。試圖找出這個解決方案,我做了下一個簡化的例子。但它顯示在發生變化的列的所有單元的單元的最後的值,並且都在紅:
視圖模型:
using System;
using System.ComponentModel;
using System.Data;
namespace WpfApplication1
{
class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
//private Model _Model; //for clarity left out
private DataTable _propDataTable;
public DataTable propDataTable
{
get { return _propDataTable; }
set
{
_propDataTable = value;
NotifyPropertyChanged("propDataTable");
}
}
private DataTable propCopyDataTable;
private string _sB;
public string sB
{
get { return _sB; }
set
{
_sB = value;
NotifyPropertyChanged("sB");
}
}
private bool _bB = false;
public bool bB
{
get { return _bB; }
set
{
_bB = value;
NotifyPropertyChanged("bB");
}
}
public ViewModel()
{
propDataTable = new DataTable();
propDataTable.Columns.Add("A", typeof(string));
propDataTable.Columns.Add("B", typeof(string));
DataRow row0 = propDataTable.NewRow();
DataRow row1 = propDataTable.NewRow();
row0[0] = "A0";
row0[1] = "B0";
row1[0] = "A1";
row1[1] = "B1";
propDataTable.Rows.Add(row0);
propDataTable.Rows.Add(row1);
propCopyDataTable = propDataTable.Copy();
//now set a different value in propCopyDataTable
propCopyDataTable.Rows[1][1] = "Changed";
//find out which cells in column B are different
//try to show in red text which cell changed
for (int i = 0; i < propDataTable.Rows.Count; i++)
{
DataRow dr = propDataTable.Rows[i];
DataRow drc = propCopyDataTable.Rows[i];
sB = (string) dr["B"];
if (dr["B"].ToString().Equals(drc["B"].ToString()))
{
bB = true;
}
else
{
bB = false;
}
}
}
}
}
的ObjectToForegroundConverter:
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
namespace WpfApplication1
{
[ValueConversion(typeof(object), typeof(SolidColorBrush))]
public class ObjectToForegroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
SolidColorBrush b = new SolidColorBrush(Colors.Black);
try
{
bool changedValue = (bool)value;
if (changedValue)
{
b = Brushes.Red;
}
}
catch (Exception e)
{
MessageBox.Show(string.Format("Error: {0}", e));//instance not set to a etc.
}
return b;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
The BindingProxy converter:
using System.Windows;
namespace WpfApplication1
{
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}
}
的XAML控制:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myViewModel="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<myViewModel:ViewModel/>
</Window.DataContext>
<Window.Resources>
<myViewModel:ObjectToForegroundConverter x:Key="MyObjectToForegroundConverter"/>
<myViewModel:BindingProxy x:Key="proxy" Data="{Binding}" />
<DataTemplate x:Key="changedBColumn" >
<TextBlock
Text="{Binding Data.sB,Source={StaticResource proxy},Mode=OneWay}"
Foreground="{Binding Data.bB,Converter={StaticResource MyObjectToForegroundConverter},Source={StaticResource proxy},Mode=OneWay}"
/>
</DataTemplate>
</Window.Resources>
<Grid>
<DataGrid x:Name="myXAMLtable" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn"
ItemsSource="{Binding propDataTable}">
</DataGrid>
</Grid>
</Window>
後面的代碼:
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
switch (e.Column.Header.ToString())
{
case "B":
{
DataGridTemplateColumn BTemplateColumn = new DataGridTemplateColumn();
BTemplateColumn.Header = "B";
BTemplateColumn.CellTemplate = (DataTemplate)Resources["changedBColumn"];
e.Column = BTemplateColumn;
break;
}
}
}
}
}
感謝您的理解。它工作得很好! –