2017-05-03 37 views
6

Tworzę aplikację do czatu i chcę utworzyć typowy dymek zawierający każdą wiadomość. I utworzeniu obiektu ścieżka w Blend (w XAML) tak:Jak utworzyć dymek w UWP?

enter image description here

Problem polega na tym, że ścieżka jest zaprojektował mieć określoną szerokość i wysokość i chciałbym to owinąć wokół tekstu bez rozciągania, dzięki czemu nie będzie wyglądał na zdeformowany, jak na granicy.

Jak mogę sprawić, aby zachowywała się tak, jak chcę?

+0

Jeśli ja zrozumiałem chcesz mieć coś podobnego ten http://take.ms/wkOLq? –

+0

Tak! to jest to! – SuperJMN

+1

Co stanie się, gdy pojawi się duży tekst? Czy chcesz rozciągać się na wysokość, ale nie przez szerokość? Jeśli tak, podaj ustaloną względną szerokość. – AVK

Odpowiedz

6

można używać w połączeniu z 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> 

który wygląda tak:

Screenshot 1

EDIT:

Wersja z ramką:

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

To nie jest chyba najprostszy i najlepszy sposób, jak to zrobić, może Path będzie lepiej to zrobić, ale to działa:

Screenshot 2

+0

Tak, właśnie tego potrzebuję! Będzie działać tak długo, dopóki nie umieścisz obrysu w dymku. Jak zrobiłbyś to z granicą? – SuperJMN

+1

@SuperJMN Zaktualizowałem swoją odpowiedź. –

+0

Dzięki, ale to nie działa dla mnie. Wielokąt nie ma granicy :( – SuperJMN

1

Oto kontrola klienta, który deklaruje Właściwość Dependency dla Tekstu i ponowne użycie niektórych właściwości kontrolki podstawowej w swoim szablonie (Tło, Szerokość, Wysokość).

Pierwsza definicja klasy: (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); } 
    } 
} 

Dzięki domyślnym szablonie (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> 

Trzeba importować ten zasób do swojego zasobu aplikacji za pomocą czegoś takiego w swojej 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> 

I na koniec przykładowa strona testowa, która używa tej kontrolki z powiązaniami na szerokość, wysokość (w oparciu o suwaki) i tekst, który musi być wyświetlony.

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

Oto wynik:

Final result: bubble with basic binding test

Zauważ, że moja odpowiedź jest dostosowany z tego jednego: WPF speech bubble

+0

To jest poprawna odpowiedź, ale podobają mi się inne dzięki @Marian Dolinský więcej, ponieważ bazuje na siatce, która rozwija się automatycznie wypełniając dostępną przestrzeń bez użycia szerokości/wysokości. Wystarczy zmienić wyrównanie siatki głównej, otrzymasz ten efekt. Dzięki za Twoje podejście! To może być przydatne dla kogoś innego. – SuperJMN