我对WPF中的数据绑定DataGrid有疑问。我使用的是VS 2010 Beta 2,它有自己的DataGrid,而不是Toolkit,虽然我认为它几乎是一样的。
我想绑定到一个包含52列的数据集,一年中每周都有一列。出于这个原因,我想动态绑定数据而不是指定每个字段。每个字段的值都是真或假,具体取决于某些条件。基于此值,我想在条件为真时在单元格模板中显示图像,如果条件不为真,则隐藏它。
我的问题是,我找到的所有使用模板的示例都是指固定的预定义字段的情况,您可以在其中使用Text =“{Binding UserName}”这样的绑定。这对我没有好处,因为我不知道在设计时字段名称会是什么。
我已经编写了一个简化的例子来说明问题。在此示例中,生成包含true和false值的数据表。我的模板中的图像永远不可见。如何根据数据中的真值或假值使其不可见?
<Window.Resources>
<!--This is the bit that doesn't work...-->
<Style TargetType="{x:Type Image}" x:Key="HideWhenFalse">
<Setter Property="Visibility" Value="Hidden" />
<Style.Triggers>
<DataTrigger
Binding="{Binding Path=???}"
Value="True"> <!--What to put for the path? -->
<Setter Property="Visibility">
<Setter.Value>
Visible
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<!--Up to here-->
<Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<Image Source="Images/tick.bmp" Style="{StaticResource HideWhenFalse}">
</Image>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<DataGrid
x:Name="myDataGrid"
AutoGenerateColumns="True" >
</DataGrid>
</Grid>
代码背后:
public partial class MainWindow:Window {
public MainWindow()
{
InitializeComponent();
DataTable dtTable = new DataTable();
dtTable.Columns.Add("A", typeof(Boolean));
dtTable.Columns.Add("B", typeof(Boolean));
dtTable.Columns.Add("C", typeof(Boolean));
dtTable.Columns.Add("D", typeof(Boolean));
dtTable.Columns.Add("E", typeof(Boolean));
dtTable.Columns.Add("F", typeof(Boolean));
for (int i = 0; i < 5; i++)
{
object[] oValues = new Object[dtTable.Columns.Count];
for (int j = 0; j < dtTable.Columns.Count; j++)
{
oValues[j] = (j % 2 == 1) ? true : false;
}
dtTable.Rows.Add(oValues);
}
myDataGrid.ItemsSource = dtTable.DefaultView;
myDataGrid.Items.Refresh();
}
}
注意这可能是显而易见的,我正以完全错误的方式解决问题。这是一个坦白:我一直试图让我的头脑绕过WPF几个月了,我似乎仍然发现自己以错误的方式接近每个问题。我希望便士很快就会下降。
答案 0 :(得分:9)
您可以使用MultiBinding
,第一个绑定从单元格(即行)获取实际数据上下文,第二个绑定从列中获取。从那里,您可以检索单元格值。
转换器代码:
public class RowColumnToCellConverter : IMultiValueConverter {
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
DataRowView row = values[0] as DataRowView;
DataGridColumn column = values[1] as DataGridColumn;
return row != null && column != null
? row[column.SortMemberPath]
: DependencyProperty.UnsetValue;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
throw new NotSupportedException();
}
}
XAML:
<Style x:Key="{x:Type DataGridCell}" TargetType="{x:Type DataGridCell}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<TextBlock x:Name="TextOK" Text="OK" Visibility="Collapsed" />
</StackPanel>
<ControlTemplate.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource RowColumnToCellConverter}">
<Binding />
<Binding RelativeSource="{x:Static RelativeSource.Self}" Path="Column" />
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="TextOK" Property="Visibility" Value="Visible" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我使用TextBlock
代替图像进行测试,但代码将是相同的。如果可以直接以DataGridCell
的样式完成,请避免为图像定义样式。