在后面的代码中创建自定义数据绑定工具提示

时间:2012-04-11 15:20:08

标签: wpf tooltip code-behind

我如何在后面的代码中创建这样的东西?

<Style x:Key="{x:Type ToolTip}" TargetType="ToolTip">
            <Setter Property="OverridesDefaultStyle" Value="true"/>
            <Setter Property="HasDropShadow" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ToolTip">
                        <Border CornerRadius="5" HorizontalAlignment="Center" VerticalAlignment="Top" Padding="1" BorderThickness="1,1,1,1">
                            <Border.Background>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#F7D073" Offset="0"/>
                                    <GradientStop Color="#F1A62F" Offset="1"/>
                                </LinearGradientBrush>
                            </Border.Background>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <Border HorizontalAlignment="Stretch" BorderThickness="0,0,0,1" BorderBrush="Black" Margin="5" Grid.ColumnSpan="2">
                                    <TextBlock FontSize="14" TextAlignment="Left" Text="{TemplateBinding Content}"/>
                                </Border>
                                <TextBlock Grid.Column="0" Grid.Row="1" Margin="10,0,5,0">Column1:</TextBlock>
                                <TextBlock Grid.Column="1" Grid.Row="1" FontWeight="Bold" Text="{Binding Column1}"  TextAlignment="Left" />
                                <TextBlock Grid.Column="0" Grid.Row="2" Margin="10,0,5,0">Column2:</TextBlock>
                                <TextBlock Grid.Column="1" Grid.Row="2" FontWeight="Bold" Text="{Binding Column2}" TextAlignment="Left" />
                                <TextBlock Grid.Column="0" Grid.Row="3" Margin="10,0,5,0">Column3:</TextBlock>
                                <TextBlock Grid.Column="1" Grid.Row="3" FontWeight="Bold" Text="{Binding Column3}" TextAlignment="Left" />
                                <TextBlock Grid.Column="0" Grid.Row="4" Margin="10,0,5,0">Column4:</TextBlock>
                                <TextBlock Grid.Column="1" Grid.Row="4" FontWeight="Bold" Text="{Binding Column4}" TextAlignment="Left" />
                                <TextBlock Grid.Column="0" Grid.Row="5" Margin="10,0,5,0">Column5:</TextBlock>
                                <TextBlock Grid.Column="1" Grid.Row="5" FontWeight="Bold" Text="{Binding Column5}" TextAlignment="Left" />
                                <TextBlock Grid.Column="0" Grid.Row="6" Margin="10,0,5,0">ColumnX:</TextBlock>
                                <TextBlock Grid.Column="1" Grid.Row="6" FontWeight="Bold" Text="{Binding ColumnX}" TextAlignment="Left" />
                            </Grid>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

我们的想法是将DataTable传递给具有未知列数的控件,并且能够构建一个工具提示,其中包含很多列。

上面的代码用于构建一个非常具体的案例,但现在我想尽可能地使用它,但是我对WPF代码隐藏的了解不是创建这样的东西所需的。

1 个答案:

答案 0 :(得分:0)

所以我无法使用工具提示中的网格执行此操作,但我可以使用stackpanels

解决方案是一个多阶段的approch。首先覆盖ToolTip的默认样式

        var style = new Style {TargetType = typeof (ToolTip)};
        style.Setters.Add(new Setter {Property = TemplateProperty, Value = GetToolTip(dataTable)});
        style.Setters.Add(new Setter{Property = OverridesDefaultStyleProperty, Value = true});
        style.Setters.Add(new Setter{Property = System.Windows.Controls.ToolTip.HasDropShadowProperty, Value = true});
        Resources.Add(typeof(ToolTip), style);

然后为TemplateProperty setter创建模板,GetToolTip()函数的内容如下所示

   private ControlTemplate GetToolTip(DataTable dt) {

        //Create Template where all factories will be assigned to
        var templateTT = new ControlTemplate(typeof (ToolTip));

        //Main border and background of the ToolTip
        var borderFactory = new FrameworkElementFactory(typeof (Border));
        borderFactory.SetValue(Border.CornerRadiusProperty, new CornerRadius(5));
        borderFactory.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Center);
        borderFactory.SetValue(VerticalAlignmentProperty, VerticalAlignment.Top);
        borderFactory.SetValue(PaddingProperty, new Thickness(1, 1, 1, 1));
        borderFactory.SetValue(BorderThicknessProperty, new Thickness(1,1,1,1));

        //Brush for the background
        var borderBrush = new LinearGradientBrush {EndPoint = new Point(.5, 1), StartPoint = new Point(.5, 0)};
        borderBrush.GradientStops.Add(new GradientStop(Color.FromArgb(255,247,208,115),0));
        borderBrush.GradientStops.Add(new GradientStop(Color.FromArgb(255, 241, 166, 47), .5));

        //Assign the brush to the backgfound property of the border
        borderFactory.SetValue(BackgroundProperty, borderBrush);

        //Main Vertical StackPanel that will contain all the horizontal stackpanels
        var verticalStackFactory = new FrameworkElementFactory(typeof (StackPanel));
        verticalStackFactory.SetValue(StackPanel.OrientationProperty, Orientation.Vertical);

        foreach (DataColumn item in dt.Columns) {

            //ID column is to be igoned and not shown on the tooltip
            if(item.ColumnName.Equals("ID")) continue;

            //Name column will be used as the "Header" of the tooltip
            if (item.ColumnName.Equals("Name")) {
                var headerStackFactory = new FrameworkElementFactory(typeof(StackPanel));
                headerStackFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

                //border of the header (to create the underline)
                var headerBorderBrush = new FrameworkElementFactory(typeof (Border));
                headerBorderBrush.SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
                headerBorderBrush.SetValue(BorderThicknessProperty, new Thickness(0, 0, 0, 1));
                headerBorderBrush.SetValue(BorderBrushProperty, new SolidColorBrush(Colors.Black));
                headerBorderBrush.SetValue(MarginProperty, new Thickness(5));

                //Text of the header bound to the Name column
                var headerTextBox = new FrameworkElementFactory(typeof (TextBlock));
                headerTextBox.SetValue(FontSizeProperty, 14.0);
                headerTextBox.SetValue(TextBlock.TextAlignmentProperty, TextAlignment.Left);
                headerTextBox.SetValue(ForegroundProperty, new SolidColorBrush(Colors.Black));
                headerTextBox.SetBinding(TextBlock.TextProperty, new Binding("Name"));

                headerBorderBrush.AppendChild(headerTextBox);
                headerStackFactory.AppendChild(headerBorderBrush);
                verticalStackFactory.AppendChild(headerStackFactory);
            }
            else {
                //Horizontal Stack Panel
                var horizontalStackFactory = new FrameworkElementFactory(typeof (StackPanel));
                horizontalStackFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

                //Add the TextBlock Label
                var factoryLabel = new FrameworkElementFactory(typeof (TextBlock));
                factoryLabel.SetValue(MarginProperty, new Thickness(10, 0, 5, 0));
                factoryLabel.SetValue(ForegroundProperty, new SolidColorBrush(Colors.Black));
                factoryLabel.SetValue(TextBlock.TextProperty, string.Format("{0}: ", item.ColumnName.Replace("_", " ")));
                horizontalStackFactory.AppendChild(factoryLabel);

                //Add the TextBlock Value bound to the column name
                var factoryText = new FrameworkElementFactory(typeof (TextBlock));
                factoryText.SetValue(FontWeightProperty, FontWeights.Bold);
                factoryText.SetValue(ForegroundProperty, new SolidColorBrush(Colors.Black));
                factoryText.SetValue(TextBlock.TextAlignmentProperty, TextAlignment.Left);
                factoryText.SetBinding(TextBlock.TextProperty, new Binding(item.ColumnName));
                horizontalStackFactory.AppendChild(factoryText);

                verticalStackFactory.AppendChild(horizontalStackFactory);
            }
        }

        borderFactory.AppendChild(verticalStackFactory);
        templateTT.VisualTree = borderFactory;
        return templateTT;
    }

为组合框项目

创建模板
        var template = new DataTemplate();
        var textBlockFactory = new FrameworkElementFactory(typeof (TextBlock));
        textBlockFactory.SetValue(ToolTipService.ShowDurationProperty, 60000);
        textBlockFactory.SetValue(ToolTipService.InitialShowDelayProperty, 0);
        textBlockFactory.SetBinding(TextBlock.TextProperty, new Binding("Name"));
        textBlockFactory.SetBinding(ToolTipProperty, new Binding("Name"));
        template.VisualTree = textBlockFactory;

        InsurancePlanMaster.ItemTemplate = template;

这允许我创建一个绑定到数据表的自定义ComboBox,其自定义工具提示绑定到表中的其他行。