2017-05-03 111 views
6

我正在创建一个聊天应用程序,并希望创建包含每条消息的典型对话框。我创建像这样在Blend(在XAML)Path对象:如何在UWP中创建对话框?

enter image description here

的问题是,该路径被设计成具有特定的宽度和高度,我想它环绕文本没有伸展,所以它不会看起来像变形一样,像边界一样。

我该如何让它表现得像我想要的?

+0

如果我理解正确的,你想拥有像这个http://take.ms/wkOLq? –

+0

是的!而已。 – SuperJMN

+1

当有巨大的文字时会发生什么?你想拉伸高度但不是宽度?如果是,则给出一个固定的相对宽度。 – AVK

回答

6

您可以结合使用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> 

,看起来像这样:

Screenshot 1

编辑:

版本与边框:

<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

+0

是的,那正是我需要的!只要你不对讲话泡泡中风,它就会工作。你会如何处理边界? – SuperJMN

+1

@SuperJMN我已经更新了我的答案。 –

+0

谢谢,但它不适合我。多边形没有边框:( – SuperJMN

1

下面是声明了一个自定义控制文本的依赖属性并在其模板(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: bubble with basic binding test

请注意,我的回答是从这个改编:WPF speech bubble

+0

这是一个有效的答案,但我更喜欢@MarianDolinský的另一个,因为它基于一个网格,它扩展了自动填充可用空间而不使用宽度/高度。只需更改根网格的对齐方式,即可获得此效果。感谢您的方法!它可能对其他人有用。 – SuperJMN