简体   繁体   中英

WPF User Control Resources

I have a custom control extending the WPF Datagrid. Inside Custom control, the resources and control template of the grid are defined

<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>

And the VisibilityConverter defined as

[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;
        }
    }

In the usage of the control, when I attempt to declare a resources like below, run time exception is thrown at the below declaration as

'Set property 'System.Windows.ResourceDictionary.DeferrableContent' threw an exception.' Line number '368' and line position '30'.

with the inner exception

{"Cannot re-initialize ResourceDictionary instance."}

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

If I comment above Resources from the xaml, it works fine.

Could you please shed some lights what is wrong with this?

Thanks in advance.

I think you're trying to redefine the ResourceDictionary that you've created when setting up your custom control. You've already created the resource dictionary for use with the control, and you're then attempting to create it again (hence the re-initialize exception).

You could move your styling for the DataGridCell into the main template (which you wouldn't want to do in your case, because of your EvenSetter , which is presumably instance specific).

A better solution for you may be to define that style in another ResourceDictionary and reference it, or add the Style to the resources for the Window/Page where you're using the custom control (eg you could add it to the resources of a parent Grid ).

I believe you can also merge resource dictionaries, although I've never tried it: http://msdn.microsoft.com/en-us/library/aa350178.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM