【问题标题】:How to create a speech bubble in UWP?如何在 UWP 中创建对话泡泡?
【发布时间】:2017-05-03 13:15:09
【问题描述】:

我正在创建一个聊天应用程序,并希望创建包含每条消息的典型对话气泡。我在 Blend(在 XAML 中)中创建了一个 Path 对象,如下所示:

问题是路径被设计为具有指定的宽度和高度,我希望它环绕文本而不拉伸,所以它看起来不会变形,就像一个边框可以。

我怎样才能让它表现得像我想要的那样?

【问题讨论】:

  • 如果我理解正确的话,你想要这样的东西take.ms/wkOLq
  • 是的!就是这样。
  • 文本很大时会发生什么?您想按高度而不是按宽度拉伸吗?如果是,则给出一个固定的相对宽度。
  • 我想我前段时间见过Rob Caplan answering 有点类似的问题。

标签: c# .net xaml uwp


【解决方案1】:

您可以将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>

看起来像这样:

编辑:

带边框的版本:

<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 会更好,但它确实有效:

【讨论】:

  • 是的,这正是我所需要的!只要您不敲击气泡,它就会起作用。你会如何使用边框?
  • 谢谢,但这对我不起作用。多边形没有边框:(
  • 只要将多边形的描边设置为黑色
  • 这并不容易,但是感谢您对此发表评论,我刚刚意识到我忘了在那里复制一次多边形。到家了再补充。
  • @SuperJMN 我已经更新了我的答案 - 格式错误。它现在应该可以工作了:)
【解决方案2】:

这是一个自定义控件,它为 Text 声明一个依赖属性,并在其模板中重用基本控件的一些属性(背景、宽度、高度)。

首先是类定义:(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>

结果如下:

请注意,我的答案改编自这个:WPF speech bubble

【讨论】:

  • 这是一个有效的答案,但我更喜欢@Marian Dolinský 的另一个,因为它基于网格,无需使用宽度/高度即可自动扩展填充可用空间。只需更改根网格的对齐方式,即可获得此效果。感谢您的方法!它可能对其他人有用。
猜你喜欢
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 1970-01-01
  • 2020-02-19
  • 2017-10-13
  • 1970-01-01
  • 2018-04-14
  • 2015-07-25
相关资源
最近更新 更多