【发布时间】:2013-10-06 12:50:30
【问题描述】:
我正在尝试制作一个自定义控件,它基本上是一个文本框,位于数据网格列标题上方,并在数据网格列中显示总数。控件库由两个自定义控件组成:DataGridColumnTotal 包含文本框,它还包含对 DataGrid 和 ItemsSource 的引用。另一种叫做DataGridHeaderTotalControl,它基本上是一种以DataGridColumnHeader为目标的样式。此样式将 DataGridColumnTotal 控件置于现有 DatagridColumnHeader 上方,并将 DataGridColumnTotal 控件中的 DataGrid 和 DataGridItemsSource 字段绑定到 Datagrid 和 ItemsSource 字段。
我目前只是试图让 TextBox 显示是否设置了 IsTotalVisible 依赖项属性,但是当我尝试在 MainWindow.xaml 中设置它时它不会更新。我没有任何代码可以显示总值,因为我还没有走到那一步。
问题出现在 MainWindow.xaml 中,当尝试在 dataGridText 列中设置 ctl:DataGridColumnTotal.IsTotalVisible="True" 时。 IsTotalVisible 属性未设置为 true。但是当我将依赖属性的默认值设置为 true 时,将显示总文本框。
DataGridColumnTotal.cs
////////////////////////////////////////////////////////////////////
//DataGridColumnTotal.cs
////////////////////////////////////////////////////////////////////
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Collections;
namespace RiskControlLibrary
{
public class DataGridColumnTotal : Control
{
static DataGridColumnTotal()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DataGridColumnTotal), new FrameworkPropertyMetadata(typeof(DataGridColumnTotal)));
}
public static bool GetIsTotalVisible(
DependencyObject target)
{
return (bool)target.GetValue(IsTotalVisibleProperty);
}
public static void SetIsTotalVisible(
DependencyObject target, bool value)
{
target.SetValue(IsTotalVisibleProperty, value);
}
public static DependencyProperty IsTotalVisibleProperty =
DependencyProperty.RegisterAttached("IsTotalVisible", typeof(bool), typeof(DataGridColumnTotal),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));
}
[ValueConversion(typeof(bool), typeof(Visibility))]
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if ((bool)value)
return Visibility.Visible;
else
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new Exception("Not Implemented.");
}
}
}
DataGridHeaderTotalControl.cs
////////////////////////////////////////////////////////////////////
//DataGridHeaderTotalControl.cs
////////////////////////////////////////////////////////////////////
using System.Windows;
using System.Windows.Controls;
namespace RiskControlLibrary
{
public class DataGridHeaderTotalControl : Control
{
static DataGridHeaderTotalControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DataGridHeaderTotalControl), new FrameworkPropertyMetadata(typeof(DataGridHeaderTotalControl)));
}
}
}
Generic.xaml
////////////////////////////////////////////////////////////////////
//Generic.xaml
////////////////////////////////////////////////////////////////////
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:RiskControlLibrary"
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:s="clr-namespace:System;assembly=mscorlib">
<Style TargetType="{x:Type local:DataGridColumnTotal}">
<Style.Resources>
<local:BoolToVisibilityConverter x:Key="booleanToVisibilityConverter" />
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:DataGridColumnTotal}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<TextBox
x:Name="PART_TextBoxTotal"
IsReadOnly="True"
VerticalAlignment="Top"
VerticalContentAlignment="Center"
Text="{Binding Total,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:DataGridColumnTotal}}}"
Visibility="{Binding IsTotalVisible, RelativeSource={RelativeSource TemplatedParent},
Converter={StaticResource booleanToVisibilityConverter}}"
>
</TextBox>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type DataGridColumnHeader}"
x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:DataGridHeaderTotalControl},
ResourceId=DataGridHeaderTotalControlStyle}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<local:DataGridColumnTotal Margin="1" Grid.Column="0" Grid.Row="0"/>
<theme:DataGridHeaderBorder Grid.Column="0" Grid.Row="1" SortDirection="{TemplateBinding SortDirection}"
IsHovered="{TemplateBinding IsMouseOver}"
IsPressed="{TemplateBinding IsPressed}"
IsClickable="{TemplateBinding CanUserSort}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding ="{TemplateBinding Padding}"
SeparatorVisibility="{TemplateBinding SeparatorVisibility}"
SeparatorBrush="{TemplateBinding SeparatorBrush}">
<TextBlock Grid.Column="0" Grid.Row="1" Text="{TemplateBinding Content}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
TextWrapping="Wrap"></TextBlock>
</theme:DataGridHeaderBorder>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MainWindow.xaml
////////////////////////////////////////////////////////////////////
//MainWindow.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:app="clr-namespace:WpfApplication1"
xmlns:ctl="clr-namespace:RiskControlLibrary;assembly=RiskControlLibrary"
Title="MainWindow" Height="341" Width="452"
Loaded="Window_Loaded">
<Grid>
<DataGrid
Name="m_dgOrder"
ItemsSource="{Binding ListPos}"
GridLinesVisibility="None"
AutoGenerateColumns="False"
IsReadOnly="True"
Background="White"
CanUserResizeRows="False"
HeadersVisibility="Column"
RowHeaderWidth="0"
ColumnHeaderStyle="{StaticResource {ComponentResourceKey
TypeInTargetAssembly={x:Type ctl:DataGridHeaderTotalControl},
ResourceId=DataGridHeaderTotalControlStyle}}">
<DataGrid.Columns>
<DataGridTextColumn Header="Symbol" Binding="{Binding Path=Symbol}"/>
<DataGridTextColumn Header="Pos" Binding="{Binding Path=Pos}" ctl:DataGridColumnTotal.IsTotalVisible="True"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
【问题讨论】:
-
要查看的代码太多,但据我所知,您正在尝试将依赖项属性用作附加属性,这是有意的吗?我认为您正在寻找继承的附加属性。
-
我不确定它是否应该附加。我尝试使用 RegisterAttached,但这也不起作用。根据 MainWindow.xaml 中的设置方式,它是否需要成为附加属性?
-
据我所知,您有一个 DataGridTextColumn 并且您设置了 ctl:DataGridColumnTotal.IsTotalVisible="True" 这显然是附加属性的语法。但物业不附。此外,它不是继承的,因此任何子 DataGridColumnTotal 类都不能使用该属性,我猜这就是您想要的。所以让它附加并给它 FrameworkPropertyMetadataOptions.Inherits 而不是 None。看看这是否有效。您可能还需要调整附加属性的绑定。
-
不幸的是,这不起作用。我将其更改为: public static DependencyProperty IsTotalVisibleProperty = DependencyProperty.RegisterAttached("IsTotalVisible", typeof(bool), typeof(DataGridColumnTotal), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));
-
我同意@dowhilefor,这有点太多代码了。您可能会得到愿意为您调试的人,但如果不是,我建议您尽可能减少它,删除与您的问题不直接相关的 所有内容,然后您将获得获得答案的机会更大。
标签: c# wpf custom-controls