WPF: Data Binding A Slider Value To A ToolTip Cont

2019-05-04 17:34发布

In a C# based WPF UserControl, I have a set of Sliders to adjust the Red,Green and Blue values of a Color element; essentially the UserControl is a color picker. I have a combination of XAML and C# code behind for the ToolTipOpening Event Handler that allows me to set the individual integer value representing the Color component property value. So, if I have the slider positioned for adjusting the amount of Red in the color in the middle of the Slider, the ToolTip will display "Red: 125", as each Color component property value can range from 0 to 255. The code fragments below for both the XAML and C# work as expected:

XAML:

<UserControl x:Class="CustomColorPicker.ColorPickerUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Name="colorPicker">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="50" />
            <ColumnDefinition Width="175" />
            <ColumnDefinition Width="100" />
        </Grid.ColumnDefinitions>

        <Label HorizontalAlignment="Right">Red:</Label>
        <Slider Grid.Row="0" Grid.Column="1" Name="sliderRed" Minimum="0" Maximum="255"
                Margin="{Binding ElementName=colorPicker, Path=Padding}"
                Value="{Binding ElementName=colorPicker, Path=Red}" 
                ToolTipOpening="OnColorSliderToolTipOpening" 
                ToolTip="Red: 0" />

        <Label Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right">Green:</Label>
        <Slider Grid.Row="1" Grid.Column="1" Name="sliderGreen" Minimum="0" Maximum="255"
                Margin="{Binding ElementName=colorPicker, Path=Padding}"
                Value="{Binding ElementName=colorPicker, Path=Green}" 
                ToolTipOpening="OnColorSliderToolTipOpening" ToolTip="Green: 0" />

        <Label Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right">Blue:</Label>
        <Slider Grid.Row="2" Grid.Column="1" Name="sliderBlue" Minimum="0" Maximum="255"
                Margin="{Binding ElementName=colorPicker, Path=Padding}"
                Value="{Binding ElementName=colorPicker, Path=Blue}" 
                ToolTipOpening="OnColorSliderToolTipOpening" ToolTip="Blue: 0" />

        <Rectangle Grid.Column="2" Grid.RowSpan="3"
                   Margin="{Binding ElementName=colorPicker, Path=Padding}"
                   Width="85" Stroke="Black" StrokeThickness="1">
            <Rectangle.Fill>
                <SolidColorBrush Color="{Binding ElementName=colorPicker, Path=Color}" />
            </Rectangle.Fill>
        </Rectangle>    
    </Grid>
</UserControl>

C#:

    private void OnColorSliderToolTipOpening(object sender, ToolTipEventArgs e)
    {
        Slider slider = (Slider) sender;

        string colorName = "N/A";
        int colorValue = 0;

        if (slider.Name == "sliderRed")
        {
            colorName = "Red";
            colorValue = (int) Color.R;                
        }

        else if (slider.Name == "sliderGreen")
        {
            colorName = "Green";
            colorValue = (int) Color.G;
        }

        else if (slider.Name == "sliderBlue")
        {
            colorName = "Blue";
            colorValue = (int) Color.B;
        }

        string colorTip =
        string.Format("{0}: {1}", colorName, colorValue.ToString());

        slider.ToolTip = colorTip;

        return;
    }

Is there a way to eliminate the code behind and set the ToolTip contents to display the same string using the ToolTip.Content and ToolTip.ContentStringFormat properties in XAML only, allowing for the elimination of the ToolTipOpening event handler in the code behind in C#? I've tried the following XAML using DataBinding to format the content string of the Slider's ToolTip:

XAML:

    <Slider Grid.Row="2" Grid.Column="1" Name="sliderBlue" Minimum="0" Maximum="255"
            Margin="{Binding ElementName=colorPicker, Path=Padding}"
            Value="{Binding ElementName=colorPicker, Path=Blue}">
        <Slider.ToolTip>
            <ToolTip
                Content="{Binding ElementName=colorPicker, Path=Blue}"
                ContentStringFormat="{}Blue: {0}" />
        </Slider.ToolTip>
    </Slider>

and the ToolTip Popup display comes up empty:

*Slider with Empty ToolTip using XAML only*

1条回答
女痞
2楼-- · 2019-05-04 18:27

Binding per ElementName just like RelativeSource with FindAncestor isn't in scope because ToolTip is a Popup which isn't part of the VisualTree (it creates its own). But you can use the ToolTip.PlacementTarget Property to get the Slider control and catch the Value.

<Slider.ToolTip>
    <ToolTip Content="{Binding RelativeSource={RelativeSource Self},
                               Path=PlacementTarget.Value}"
             ContentStringFormat="Blue: {0:0}" />
</Slider.ToolTip>

Please note the additional :0 in ContentStringFormat="Blue: {0:0}" to round the Value.

查看更多
登录 后发表回答