How to create a speech bubble in UWP?

I am creating a chat application and want to create a typical speech bubble containing each message. I created a Path object in Blend (in XAML) as follows:

enter image description here

The problem is that the path was designed to have the specified width and height, and I would like the text to be wrapped without stretching, so it won’t look warped like the border does.

How can I make him behave the way I want?

+6
source share
2 answers

You can use Polygonin combination with StackPanel:

<StackPanel Orientation="Horizontal"
            HorizontalAlignment="Left"
            Padding="6"
            >
    <Polygon Points="0,0 15,0 15,15"
             Fill="LightGray"
             Margin="0,10,0,0"
             />

    <Border Background="LightGray"
            CornerRadius="3"
            Padding="6"
            VerticalAlignment="Top"
            >
        <TextBlock Text="Text"
                   TextWrapping="WrapWholeWords"
                   Width="100"
                   Height="50"
                   />
    </Border>
</StackPanel>

which is as follows:

Screenshot 1

EDIT:

Version with frame:

<Grid HorizontalAlignment="Left"
      Padding="6"
      >
    <Polygon Points="0,0 15,0 15,15"
             Fill="LightGray"
             Stroke="Black"
             Margin="0,10,0,0"
             />

    <Border Background="LightGray"
            BorderBrush="Black"
            BorderThickness="0.5"
            CornerRadius="3"
            Padding="6"
            Margin="14,0,0,0"
            VerticalAlignment="Top"
            >
        <TextBlock Text="Text"
                   TextWrapping="WrapWholeWords"
                   Width="100"
                   Height="50"
                   />
    </Border>

    <Polygon Points="0,0 15,0 15,15"
             Fill="LightGray"
             Margin="0,10,0,0"
             />
</Grid>

, , , , , Path , :

Screenshot 2

+6

, Dependency (Background, Width, Heigth).

: (SpeechBubbleControl.xaml.cs)

[TemplatePart(Name = PartBubbleText, Type = typeof(TextBlock))]
public sealed partial class SpeechBubbleControl : Control
{
    private const string PartBubbleText = "BubbleText";
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof(Text), typeof(string), typeof(SpeechBubbleControl), new PropertyMetadata(""));

    public SpeechBubbleControl()
    {
        DefaultStyleKey = typeof(SpeechBubbleControl);
    }

    public string Text
    {
        get { return GetValue(TextProperty).ToString(); }
        set { SetValue(TextProperty, value); }
    } 
}

(SpeechBubbleControl.xaml):

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="using:App6"
                    >

    <Style TargetType="local:SpeechBubbleControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:SpeechBubbleControl">
                    <Grid Background="{TemplateBinding Background}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <Rectangle Fill="{TemplateBinding Background}" Stroke="#FF000000" RadiusX="10" RadiusY="10"/>
                        <Path Fill="{TemplateBinding Background}" Stretch="Fill" Stroke="#FF000000" HorizontalAlignment="Left" Margin="-15,-5,0,20" Width="30" Height="40" Data="M0,0 L15,40 30,20 0,0" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False">
                            <Path.RenderTransform>
                                <CompositeTransform Rotation="-20"/>
                            </Path.RenderTransform>
                        </Path>
                        <Rectangle Fill="{TemplateBinding Background}" RadiusX="10" RadiusY="10" Margin="1"/>
                        <TextBlock Name="BubbleText" HorizontalAlignment="Center" VerticalAlignment="Center" 
                                   Text="{TemplateBinding Text}" FontSize="20" TextWrapping="Wrap"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

, - app.xaml:

<Application
    x:Class="App6.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App6"
    RequestedTheme="Light">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="SpeechBubbleControl.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

, , , , ( ) , .

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="40"/>
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBox x:Name="testText" Grid.ColumnSpan="2"  PlaceholderText="My text..." />
        <Slider x:Name="width" Grid.Row="1" Minimum="50" Maximum="500" Value="200" />
        <Slider x:Name="height" Grid.Row="1"  Grid.Column="2" Minimum="50" Maximum="500" Value="100" />

        <local:SpeechBubbleControl Grid.Row="2" Grid.ColumnSpan="2"
                                   Width="{Binding Value, ElementName=width}"
                                   Height="{Binding Value, ElementName=height}" 
                                   Text="{Binding Text, ElementName=testText, FallbackValue=Hello}"
                                   Background="Beige" >
        </local:SpeechBubbleControl>
    </Grid>

    <local:SpeechBubbleControl Grid.Row="2" Grid.ColumnSpan="2"
        Width="{Binding Value, ElementName=width}" Height="{Binding Value, ElementName=height}" 
                               Text="{Binding Text, ElementName=testText, FallbackValue=Hello}"
                               Background="Beige" >

    </local:SpeechBubbleControl>
</Grid>

:

Final result: a bubble with basic snap testing

, : WPF

+1

Source: https://habr.com/ru/post/1016957/


All Articles