简体   繁体   English

如何在UWP中创建一个讲话泡泡?

[英]How to create a speech bubble in UWP?

I'm creating a chat application and would like to create the typical speech bubble that contains each message. 我正在创建一个聊天应用程序,并希望创建包含每条消息的典型语音气泡。 I created a Path object in Blend (in XAML) like this: 我在Blend中创建了一个Path对象(在XAML中),如下所示:

在此输入图像描述

The problem is that the path is has designed to have a specified width and height and I would like it to wrap around the text without stretching, so it won't look deformed, like a border does. 问题是路径设计为具有指定的宽度和高度,并且我希望它没有拉伸情况下环绕文本 ,因此它不会像边框那样看起来变形。

How can I make it behave like I want? 我怎样才能让它表现得像我想要的那样?

You may use Polygon in combination with StackPanel : 您可以将PolygonStackPanel结合使用:

<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 looks like this: 看起来像这样:

截图1

EDIT: 编辑:

Version with border: 带边框的版本:

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

This is probably not the easiest and the best way how to do this, maybe Path will be better to do this, but it works: 这可能不是最简单和最好的方法,也许Path会更好地做到这一点,但它的工作原理:

截图2

Here is a Custom control that declares a Dependency Property for the Text and reuse some properties of the base control in its template (Background, Width, Heigth). 这是一个Custom控件,它声明Text的Dependency属性,并在其模板(Background,Width,Heigth)中重用基本控件的一些属性。

First the class definition: ( SpeechBubbleControl.xaml.cs ) 首先是类定义:( 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); }
    } 
}

With its default template ( SpeechBubbleControl.xaml ): 使用其默认模板( 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>

You have to import this resource into your application resource using something like this in your app.xaml : 您必须在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>

And finally a sample test page, which use this control with bindings on width, height (based on the sliders) and the text that must be displayed. 最后是一个示例测试页面,它使用此控件绑定宽度,高度(基于滑块)和必须显示的文本。

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

Here is the result: 结果如下:

最终结果:基本绑定测试的泡沫

Note that my answer is adapted from this one: WPF speech bubble 请注意,我的答案改编自这一个: WPF语音泡沫

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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