c# - WPF 用户控制资源

标签 c# wpf wpf-controls custom-controls

我有一个扩展 WPF 数据网格的自定义控件。 Custom控件内部定义了网格的资源和控件模板

<DataGrid.Resources>
        <local:VisibilityConverter x:Key="visibilityConverter" />
 <Style x:Key="ColumnHeaderGripperStyle" TargetType="{x:Type Thumb}">
            <Setter Property="Width" Value="8" />
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Cursor" Value="SizeWE" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Thumb}">
                        <Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>



        <!--May need Commented if clashes with other Styles-->
        <Style TargetType="{x:Type DataGridColumnHeader}" x:Key="DataGridColumnHeaderStyle">
            <Setter Property="Foreground" Value="#FF000000" />
            <Setter Property="HorizontalContentAlignment" Value="Left" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="IsTabStop" Value="False" />
            <Setter Property="SeparatorBrush" Value="#FFC9CACA" />
            <Setter Property="Padding" Value="4" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="DataGridColumnHeader">
                        <Grid x:Name="Root" Height="48">
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition Height="26" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Fill).Color" Duration="0" To="#FF448DCA" />
                                            <ColorAnimation Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Fill).(GradientStops)[3].Color" Duration="0" To="#7FFFFFFF" />
                                            <ColorAnimation Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Fill).(GradientStops)[2].Color" Duration="0" To="#CCFFFFFF" />
                                            <ColorAnimation Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Fill).(GradientStops)[1].Color" Duration="0" To="#F2FFFFFF" />
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="BackgroundRectangle" Storyboard.TargetProperty="(Fill).Color" Duration="0" To="#FF448DCA" />
                                            <ColorAnimation Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Fill).(GradientStops)[0].Color" Duration="0" To="#D8FFFFFF" />
                                            <ColorAnimation Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Fill).(GradientStops)[1].Color" Duration="0" To="#C6FFFFFF" />
                                            <ColorAnimation Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Fill).(GradientStops)[2].Color" Duration="0" To="#8CFFFFFF" />
                                            <ColorAnimation Storyboard.TargetName="BackgroundGradient" Storyboard.TargetProperty="(Fill).(GradientStops)[3].Color" Duration="0" To="#3FFFFFFF" />
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="SortStates">
                                    <VisualState x:Name="Unsorted" />
                                    <VisualState x:Name="SortAscending">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="Opacity" Duration="0" To="1.0" />
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="SortDescending">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="Opacity" Duration="0" To="1.0" />
                                            <DoubleAnimation Storyboard.TargetName="SortIcon" Storyboard.TargetProperty="(RenderTransform).ScaleY" Duration="0" To="-.9" />
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Rectangle x:Name="BackgroundRectangle" Grid.ColumnSpan="2" Fill="#FF1F3B53" Stretch="Fill" />
                            <Rectangle x:Name="BackgroundGradient" Grid.ColumnSpan="2" Stretch="Fill">
                                <Rectangle.Fill>
                                    <LinearGradientBrush EndPoint=".7,1" StartPoint=".7,0">
                                        <GradientStop Color="#FCFFFFFF" Offset="0.015" />
                                        <GradientStop Color="#F7FFFFFF" Offset="0.375" />
                                        <GradientStop Color="#E5FFFFFF" Offset="0.6" />
                                        <GradientStop Color="#D1FFFFFF" Offset="1" />
                                    </LinearGradientBrush>
                                </Rectangle.Fill>
                            </Rectangle>
                            <Grid Grid.ColumnSpan="2" Margin="0,0,1,1">
                                <Border Margin="0,0,0,-1" Width="14" BorderBrush="#FF878787" BorderThickness="1,0,0,0" HorizontalAlignment="Right" Visibility="Collapsed">
                                    <Path x:Name="DropDownIndicator" Height="5.26" Margin="0,2,0,0" Width="6.334" Data="F1 M-3.0081699E-07,0.010437 L4.0493598,6.9732699 L8.0546999,0 L-3.0081699E-07,0.010437 z" Fill="#FF444444" HorizontalAlignment="Center" RenderTransformOrigin=".5,.5" Stretch="Uniform" UseLayoutRounding="False" VerticalAlignment="Center">
                                        <Path.RenderTransform>
                                            <ScaleTransform ScaleX=".9" ScaleY=".9" />
                                        </Path.RenderTransform>
                                    </Path>
                                </Border>
                            </Grid>
                            <Grid Margin="4,2,9,2" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="Auto" />

                                </Grid.ColumnDefinitions>
                                <local:ColumnOptionControl Height="13" Width="13" />
                                                           <!--Visibility="{Binding Path=CanUserGroup, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Converter={StaticResource visibilityConverter}}" />-->

                                <ContentPresenter Grid.Column="1" Content="{TemplateBinding Content}" />
                                <Path x:Name="SortIcon" Grid.Column="2" Margin="4,0,0,0" Width="8" Data="F1 M -5.215,6.099L 5.215,6.099L 0,0L -5.215,6.099 Z " Fill="#FF444444" HorizontalAlignment="Right" Opacity="0" RenderTransformOrigin=".5,.5" Stretch="Uniform" VerticalAlignment="Center">
                                    <Path.RenderTransform>
                                        <ScaleTransform ScaleX=".9" ScaleY=".9" />
                                    </Path.RenderTransform>
                                </Path>
                            </Grid>
                            <Rectangle x:Name="VerticalSeparator" Grid.Column="1" Width="1" Fill="{TemplateBinding SeparatorBrush}" VerticalAlignment="Stretch" />  <!--Visibility="{TemplateBinding SeparatorVisibility}" />-->
                            <Border Grid.ColumnSpan="2" Grid.Row="1" Margin="0" BorderBrush="#FFC9CACA" BorderThickness="0,1,1,0" Visibility="{Binding Path=CanUserFilter, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Converter={StaticResource visibilityConverter}}">
                                <local:ColumnFilterControl Margin="0,0,0,1"/> <!--FilterVisibility="{Binding Path=CanUserFilter, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Converter={StaticResource visibilityConverter}}" />-->
                            </Border>

                            <Thumb Style="{StaticResource ColumnHeaderGripperStyle}" x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" />
                            <Thumb Style="{StaticResource ColumnHeaderGripperStyle}" x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </DataGrid.Resources>

VisibilityConverter 定义为

[ValueConversion(typeof(Visibility), typeof(bool))]
    class VisibilityConverter : IValueConverter
    {

        public object  Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool? val = value as bool?;

            if (val == null) val = false;

            Visibility visible = (val == false ? Visibility.Collapsed : Visibility.Visible);
            return visible;
        }

        public object  ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Visibility? visible = value as Visibility?;
            if (visible == null) visible = Visibility.Collapsed;
            bool val = (visible == Visibility.Collapsed || visible == Visibility.Hidden ? false : true);

            return val;
        }
    }

在控件的使用中,当我尝试声明如下所示的资源时,在下面的声明处抛出运行时异常

“设置属性“System.Windows.ResourceDictionary.DeferrableContent”引发异常。”行号“368”和行位置“30”。

有内部异常

{“无法重新初始化 ResourceDictionary 实例。”}

<local:EnhancedWPFDataGrid.Resources>
                            <Style TargetType="{x:Type DataGridCell}">
                                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown"></EventSetter>
                            </Style>
                            <uc:Settings x:Key="settings"/>
                        </local:EnhancedWPFDataGrid.Resources>

如果我在 xaml 的资源上面进行评论,它就可以正常工作。

您能解释一下这有什么问题吗?

提前致谢。

最佳答案

我认为您正在尝试重新定义在设置自定义控件时创建的ResourceDictionary。您已经创建了与控件一起使用的资源字典,然后您尝试再次创建它(因此出现重新初始化异常)。

您可以将 DataGridCell 的样式移动到主模板中(在您的情况下您不想这样做,因为您的 EvenSetter 可能是特定于实例)。

对您来说更好的解决方案可能是在另一个 ResourceDictionary 中定义该样式并引用它,或者将 Style 添加到 Window/Page 的资源中 您使用自定义控件的位置(例如,您可以将其添加到父 Grid 的资源中)。

我相信你也可以合并资源字典,尽管我从未尝试过: http://msdn.microsoft.com/en-us/library/aa350178.aspx

关于c# - WPF 用户控制资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18441901/

相关文章:

c# - List<T> 怎么没有实现 Add(object value)?

wpf - 如何将 WrapPanel itemssource 设置为列表?

c# - 动态业务规则

c# - LINQ to SQL Basic 插入引发 : Attach or Add not new entity related exception

c# - 如何从 postgres 列中选择二进制数据

WPF:在没有自定义镶边的无边框窗口上放置阴影

WPF TextBox 从鼠标指针获取并设置插入符位置

wpf - 如何阻止面板的子项超出设置的面板最大宽度的范围?

c# - 如何在 WPF C# 中禁用 Web 浏览器安全警告

wpf - 按钮不覆盖父级的 IsEnabled