WPF 自定义数据网格控件不显示任何内容
本文关键字:显示 任何内 控件 网格 自定义 数据 数据网 WPF | 更新日期: 2023-09-27 17:56:37
>我有一个自定义的DataGrid控件。
类如下所示:
public static class CloneRowDataGridCommands
{
private static RoutedCommand _cloneRowRoutedCommand = new RoutedCommand();
public static RoutedCommand CloneRowRoutedCommand
{
get { return _cloneRowRoutedCommand; }
}
}
public class CloneRowDataGrid : DataGrid
{
protected Button CloneButton { get; set; }
public static readonly DependencyProperty ShowCloneColumnProperty =
DependencyProperty.Register("ShowCloneColumn",
typeof(bool),
typeof(CloneRowDataGrid),
new FrameworkPropertyMetadata(false,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnShowCloneColumnPropertyChanged));
private static void OnShowCloneColumnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
CloneRowDataGrid cloneRowDataGrid = d as CloneRowDataGrid;
if (cloneRowDataGrid != null)
{
cloneRowDataGrid.OnShowCloneColumnPropertyChanged((bool) e.OldValue, (bool) e.NewValue);
}
}
protected virtual void OnShowCloneColumnPropertyChanged(bool oldValue, bool newValue)
{
// Nothing right now
}
public static readonly RoutedEvent CloneEvent =
EventManager.RegisterRoutedEvent("Clone", RoutingStrategy.Bubble,
typeof(CloneRowRoutedEventHandler),
typeof (CloneRowDataGrid));
public event CloneRowRoutedEventHandler Clone
{
add { AddHandler(CloneEvent, value); }
remove { RemoveHandler(CloneEvent, value); }
}
protected virtual void RaiseCloneEvent()
{
// TODO: change "new object()" to the row data
CloneRowRoutedEventArgs args = new CloneRowRoutedEventArgs(CloneEvent, new object());
RaiseEvent(args);
}
static CloneRowDataGrid()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(CloneRowDataGrid),
new FrameworkPropertyMetadata(typeof(CloneRowDataGrid)));
}
public CloneRowDataGrid()
{
CommandBindings.Add(new CommandBinding(CloneRowDataGridCommands.CloneRowRoutedCommand,
ExecuteCloneRow, CanExecuteCloneRow));
}
private void CanExecuteCloneRow(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void ExecuteCloneRow(object sender, ExecutedRoutedEventArgs e)
{
// TODO: Clone row
RaiseCloneEvent(); // pass object row to the eventargs
}
public bool ShowCloneColumn
{
get { return (bool) GetValue(ShowCloneColumnProperty); }
set { SetValue(ShowCloneColumnProperty, value); }
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
// Do stuff
// TODO: Fix this to avoid memory lick if the event is already registered
// TODO: Or change to a command for the clone button
CloneButton = GetTemplateChild("PART_CloneButton") as Button;
if (CloneButton != null)
{
CloneButton.Click += OnCloneButtonClick;
}
}
private void OnCloneButtonClick(object sender, RoutedEventArgs routedEventArgs)
{
// Invoke another event that might be registered from the client
RaiseCloneEvent();
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
// Do stuff
}
protected override void OnColumnDisplayIndexChanged(DataGridColumnEventArgs e)
{
base.OnColumnDisplayIndexChanged(e);
}
}
public delegate void CloneRowRoutedEventHandler(object sender, CloneRowRoutedEventArgs e);
public class CloneRowRoutedEventArgs : RoutedEventArgs
{
public object RowObject { get; protected set; }
public CloneRowRoutedEventArgs(RoutedEvent routedEvent, object rowObject) : base(routedEvent)
{
RowObject = rowObject;
}
}
Generic.xaml 中的样式如下所示。
<Style TargetType="{x:Type uiControls:CloneRowDataGrid}" BasedOn="{StaticResource {x:Type DataGrid}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type uiControls:CloneRowDataGrid}">
<!-- Parameter should be the row -->
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer x:Name="DG_ScrollViewer" Focusable="false">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
使用控件时。
<uiControls:CloneRowDataGrid ItemsSource="{Binding SomeListCustomers}" AutoGenerateColumns="False" CanUserAddRows="False" x:Name="GridCustom"
HorizontalScrollBarVisibility="Disabled" BorderThickness="1" BorderBrush="DimGray"
ColumnHeaderStyle="{StaticResource DataGridColumnHeaderStyle}" Margin="10,0,25,0" Height="200">
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="Focusable" Value="False"/>
</Style>
</DataGrid.CellStyle>
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="White"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black"/>
<SolidColorBrush x:Key="{x:Static SystemColors.ActiveBorderColorKey}" Color="White"/>
</DataGrid.Resources>
<DataGrid.Columns>
<StaticResource ResourceKey="CloneRowButtonColumn"/>
<DataGridTemplateColumn Header="Name" Width="75" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Name}" Width="75" IsReadOnly="True" Focusable="False" IsTabStop="False"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="NickName" Width="100" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding NickName}" Width="100" IsReadOnly="True" Focusable="False" IsTabStop="False"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</uiControls:CloneRowDataGrid>
我在设计器和运行时得到的只是一个没有列的灰色边框。如果我在 XAML 窗口中更改类型 tp 数据网格,它会显示 3 列。
我肯定错过了一些东西。我不需要任何特殊的样式,我只需要 DataGrid 外观,然后使用其他功能。
目标是在需要时使用标志固定和可见列。
为了使它工作,我实际上必须删除属性="模板"部分,现在 DataGrid 样式适用。虽然这感觉像是一个黑客,并且很可能需要了解有关 DataGrid 样式覆盖的更多信息。
<Style TargetType="{x:Type uiControls:CloneRowDataGrid}" BasedOn="{StaticResource {x:Type DataGrid}}">
</Style>