如何使用行和模板以及可重复单元格获取这样的数据网格?
DataGrid绑定到一个名为Blocks的属性,这是一个Block类型的BindingList,在视图模型中定义:
<DataGrid x:Name="dgBlocks" DockPanel.Dock="Left"
Margin="20,10,10,20" AutoGenerateColumns="False"
ItemsSource="{Binding Blocks, Mode=TwoWay}"
IsSynchronizedWithCurrentItem="True"
CanUserAddRows="False"
SelectionUnit="Cell" SelectionMode="Single"
EnableColumnVirtualization="False"
EnableRowVirtualization="False"
SelectedIndex="-1" MinRowHeight="10"
LoadingRow="dg_LoadingRow"
SelectionChanged="dgBlocks_SelectionChanged"
>
<DataGrid.Resources>
<helper:BindingProxy x:Key="proxy" Data="{Binding}" />
<!--todo: change to symbol’s ‘ReadOnly’ property instead of block’s ‘Permission’ -->
<Style x:Key="CellPermissionStyle" TargetType="DataGridCell">
<Setter Property="Background" Value="{Binding Permission, Converter={StaticResource BlockPermissionToBrushConverter}}" />
<Setter Property="IsEnabled" Value="{Binding Permission, Converter={StaticResource BlockPermissionToBoolConverter}}" />
</Style>
</DataGrid.Resources>
<DataGrid.RowHeaderTemplate>
<DataTemplate>
<TextBlock Name="txtBlockRowHeader"
Text="{Binding Path=Header,
RelativeSource={RelativeSource AncestorType=DataGridRow}}">
</TextBlock>
</DataTemplate>
</DataGrid.RowHeaderTemplate>
<DataGrid.Columns>
<DataGridTemplateColumn>
<!-- Selection checkboxes -->
<DataGridTemplateColumn.Header>
<StackPanel>
<CheckBox HorizontalAlignment="Center" IsThreeState="True" ToolTip="Select All" Margin="10,0,0,0">
<CheckBox.IsChecked>
<Binding Path="DataContext.SelectAll"
RelativeSource="{RelativeSource AncestorType={x:Type UserControl}}"
Mode="TwoWay"
UpdateSourceTrigger="PropertyChanged"
/>
</CheckBox.IsChecked>
</CheckBox>
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="5,0,0,0" IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="50">
<DataGridTemplateColumn.Header>
<TextBlock Text="Repeat" HorizontalAlignment="Center" />
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<telerik:RadNumericUpDown Name="nudRepeatBlock" ValueFormat="Numeric" Width="40"
ToolTip="Repeat block number of times" IsInteger="True" IsEditable="True"
Minimum="1" Maximum="100" UpdateValueEvent="PropertyChanged"
Value="{Binding Repeat, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" MinWidth="40" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" CanUserReorder="False" CanUserResize="False"
Visibility="{Binding Data.Encoding, Converter={StaticResource Encoding8b10bToCollapsedConverter}, Source={StaticResource proxy}}">
<DataGridTextColumn.HeaderStyle>
<Style TargetType="DataGridColumnHeader">
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</DataGridTextColumn.HeaderStyle>
</DataGridTextColumn>
<!--todo: change… -->
<DataGridTextColumn Header="[0]" Binding="{Binding .Symbols[0].SymbolText, UpdateSourceTrigger=LostFocus}" CellStyle="{StaticResource CellPermissionStyle}" />
<DataGridTextColumn Header="[1]" Binding="{Binding .Symbols[1].SymbolText, UpdateSourceTrigger=LostFocus}" CellStyle="{StaticResource CellPermissionStyle}" />
<!-- … -->
<DataGridTextColumn Header="[15]" Binding="{Binding .Symbols[15].SymbolText, UpdateSourceTrigger=LostFocus}" CellStyle="{StaticResource CellPermissionStyle}" />
</DataGrid.Columns>
</DataGrid>
每个Block对象都有一个名为Symbols的属性,定义为Symbol类型的BindingList,以及其他一些属性。符号显示在带有标题[0],1等的列中 其他列中显示的其他块属性。例如。选中复选框,Reapeat,Name。
public interface ISymbol
{
int Index { get; set; }
bool ReadOnly { get; set; }
string SymbolText { get; set; }
}
public class BlockBase : ObservableObject, IDataErrorInfo
{
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value == _isSelected)
return;
_isSelected = value;
OnPropertyChanged("IsSelected");
RaiseSelectionChangedEvent();
}
}
public string Name { get; set; }
public virtual BindingList<ISymbol> Symbols { get; set; }
public BlockPermission Permission { get; set; }
public int Repeat { get; set; }
}
public class Symbol : ObservableObject, ISymbol
{
DisplayFormat Format { get; set; }
public int Index { get; set; }
public virtual bool ReadOnly { get; set; }
public virtual string SymbolText
{
get { return (Format == DisplayFormat.Binary) ? _binSymbol : _hexSymbol;
}
set
{
// … validate and set _binSymbol & _hexSymbol values
OnPropertyChanged("SymbolText");
}
}
现在,我需要绑定每个符号的单元格&#39; IsEnabled&#39;属于Symbol&#39; ReadOnly&#39;属性。
我试图在DataGrid.Resources中将其定义为CellPermissionStyle,但我不知道如何在此级别上访问Symbol。
此外,用模板替换符号的所有重复DataGridTextColumn防御将会很好。
有人会帮助我吗?
答案 0 :(得分:0)
我的研究刚刚证实,遗憾的是,对于适用于列子集的模板或样式,无法做到这一点。如Mishka建议的那样,将参数发送到样式或模板也是不可能的:(。
所以,我刚刚为我的16列中的每一列都采用'复制 - 粘贴 - 修改'单元格样式:
<DataGridTextColumn Header="[0]" Binding="{Binding .Symbols[0].SymbolText, UpdateSourceTrigger=LostFocus}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="{Binding .Symbols[0].ReadOnly, Converter={StaticResource SymbolReadOnlyToBrushConverter}}" />
<Setter Property="IsEnabled" Value="{Binding .Symbols[0].ReadOnly, Converter={StaticResource SymbolReadOnlyToEnabledConverter}}" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
...
<DataGridTextColumn Header="[15]" Binding="{Binding .Symbols[15].SymbolText, UpdateSourceTrigger=LostFocus}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="Background" Value="{Binding .Symbols[15].ReadOnly, Converter={StaticResource SymbolReadOnlyToBrushConverter}}" />
<Setter Property="IsEnabled" Value="{Binding .Symbols[15].ReadOnly, Converter={StaticResource SymbolReadOnlyToEnabledConverter}}" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
是的,我知道,这个XAML看起来很难看,但它对我有用而没有对现有代码库进行重新设计的风险。
如果有人能在XAML中建议更好,更优雅的方式,我会很高兴。