我的应用程序的最终目标是让用户比较2个数据表。我有2个DataGrid并排显示,显示了DataTables,行已重新排列,以便2个表之间的所有匹配行都对齐。
我的XAML设置类似于this question:
<DataGrid Name="comparisonGridLeft" ItemsSource="{Binding}" Margin="3" CanUserResizeRows="False">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Style.Triggers>
<DataTrigger Binding="{Binding Match}" Value="true">
<Setter Property="Background" Value="Red"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
</DataGrid>
在我的DependencyProperty中,“匹配”的定义类似于this answer:
public class CustomProperties
{
public static DependencyProperty MatchProperty =
DependencyProperty.RegisterAttached("Match",
typeof(bool),
typeof(CustomProperties),
new PropertyMetadata(null));
public static void SetMatch(DependencyObject obj, bool value)
{
obj.SetValue(MatchProperty, value);
}
public static bool GetMatch(DependencyObject obj)
{
return (bool)(obj.GetValue(MatchProperty));
}
}
我的最后一个障碍是,当我遍历DataGrid将“ Match”属性设置为正确的值时,出现错误:
错误CS1503:参数1:无法从“ System.Data.DataRowView”转换为“ System.Windows.DependencyObject”
foreach (DataRowView leftRow in leftGrid.ItemsSource)
{
foreach (DataRowView rightRow in rightGrid.ItemsSource)
{
bool foundMatch = DetermineIfMatch(leftRow, rightRow);
if (foundMatch)
{
//Throws the compile-time error
CustomProperties.SetMatch(leftRow, true);
foundCloseMatch = true;
break;
}
}
}
在此先感谢您的帮助。 WPF的新手,整天都在努力工作
答案 0 :(得分:0)
您不能在DataRowView上设置附加属性,因为如您所见,它不是DependencyObject,它是附加属性的必需项。 DataGrid的绑定源是什么?如果您控制该对象,则可以将Match属性保留在该对象中。
请注意...对我来说,您的循环可以只设置背景颜色,实际上并不需要附加的属性。
编辑:从事情的角度来看,我不会在数据表中获取数据,而是您自己的POCO:
class MyPoco
{
string PropA {get;set}
string PropB {get;set}
Color Background {get;set}
}
然后有一个List<MyPoco>
并将ItemsSource设置为此。除了自动绑定,您还必须自己定义列并将其绑定到POCO属性:
<DataGrid ItemsSource={Binding Pocos}>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding PropA}" />
现在,您可以将样式属性添加到POCO(背景属性)中。然后,您将定义一个DataGrid.RowStyle通过绑定到Background属性来设置Background。
答案 1 :(得分:0)
在这种情况下,您不能使用附加属性。这是解决问题的方法
static class CacheService { public static readonly HashSet<DataRowView> Cache = new HashSet<DataRowView>(); }
HashSet<DataRowView> _cache = CacheService.Cache; foreach (DataRowView leftRow in leftGrid.ItemsSource) { foreach (DataRowView rightRow in rightGrid.ItemsSource) { bool foundMatch = DetermineIfMatch(leftRow, rightRow); if (!foundMatch) _cache.Add(leftRow); } }
<DataGrid Name="comparisonGridLeft" ItemsSource="{Binding}" Margin="3" CanUserResizeRows="False"> <DataGrid.RowStyle> <Style TargetType="DataGridRow"> <Setter Property="Background" Value="{Binding Path=., Converter={StaticResource MatchToBrushConverter}}" /> </Style> </DataGrid.RowStyle> </DataGrid>
public class MatchToBrushConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { HashSet<DataRowView> _cache = CacheService.Cache; //Get the cache return _cache.Contains(value) ? Brushes.Red : Brushes.Transparent; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
仅供参考,我尚未对其进行测试。
希望这会有所帮助。