2017-10-10 3 views
0

Voici quelques XAML:WPF - changement ancre texte dans Canvas

<Grid Width="200" Height="200"> 
    <Canvas Background="Beige"> 
     <Line X1="0" X2="200" Y1="100" Y2="100" Stroke="Black"/> 
     <Line X1="100" X2="100" Y1="0" Y2="200" Stroke="Black"/> 
     <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Margin="2"> 
      <TextBlock.RenderTransform> 
       <TranslateTransform X="100" Y="100"/> 
      </TextBlock.RenderTransform> 
      hello world1 
      <LineBreak/> 
      hello world2 
      <LineBreak/> 
      hello world3 
     </TextBlock> 
    </Canvas> 
</Grid> 

Je veux que le texte apparaisse dans le quadrant supérieur droit de mon Canvas au lieu du quadrant inférieur droit.

Est-il possible de faire dans WPF?

Actuellement, le texte est tiré de topleft à droite, je voudrais qu'il soit tiré de bottomleft à topright. Je n'ai pas trouvé de réponse sur Internet qui fonctionne à l'intérieur d'un Canvas.

Dans mon code de production, le texte doit pouvoir être de n'importe quelle longueur et hauteur.

Edit:

on m'a demandé de fournir un échantillon entièrement travail, ainsi va ici:

XAML:

<Window x:Class="WpfApp1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApp1" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <!--The drawing area can be anything, a grid, a panel, a canvas... Can't just use specific alignment tools so I have to use a Transform--> 
     <Grid x:Name="DrawingArea" Background="Beige" MouseMove="UIElement_OnMouseMove"> 
      <TextBlock x:Name="TextBlock" Margin="2"> 
       hello world1 
       <LineBreak/> 
       hello world2 
       <LineBreak/> 
       hello world3 
      </TextBlock> 
     </Grid> 
    </Grid> 
</Window> 

code derrière:

using System.Windows.Input; 
using System.Windows.Media; 

namespace WpfApp1 
{ 
    public partial class MainWindow 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void UIElement_OnMouseMove(object sender, MouseEventArgs e) 
     { 
      var mousePos = e.GetPosition(DrawingArea); 
      TextBlock.RenderTransform = new TranslateTransform(mousePos.X, mousePos.Y); 
     } 
    } 
} 

Actuellement le texte apparaît sous le curseur de la souris Windows par défaut, je voudrais qu'il apparaisse au-dessus du curseur de la souris Windows par défaut.

+0

Alors, pourquoi ne pas vous soustrayez simplement le ActualHeight de TextBlock de mousePos.Y? – Clemens

+0

Actuellement, je connais la hauteur du texte en utilisant codebehind, mais dans mon application actuelle (basée sur MVVM) je ne peux pas obtenir la hauteur du texte. Donc, il faudrait en quelque sorte être soustrait de la 'Transform' sur le texte avec un ValueConverter ou quelque chose. Je n'ai aucune idée sur la façon de faire cela? – ManIkWeet

+0

Donc le code dans votre question ne montre pas encore ce que vous faites réellement. Comment espérez-vous obtenir un soutien ici? – Clemens

Répondre

-2

Ajouter une grille sur votre toile et définissez les propriétés HorizontalAlignment = "right" VerticalAlignment = "top"

<Canvas x:Name="newCanvas"> 
<Grid> 
    <Label Content="Hello World!" 
      HorizontalAlignment="Right" 
      VerticalAlignment="Top" 
    /> 
</Grid> 

0

Vous voyez dans la partie inférieure droite en raison de la TranslateTransform. Vous l'avez défini sur X=100, Y=100. Si vous définissez Y=0 il devrait être sur le dessus.

Mais vous devriez considérer certaines choses avec ce code:

  1. Pourquoi utiliser TranslateTransform dans une toile? Vous pouvez simplement ajouter les propriétés Canvas.Top et Canvas.Left au TextBlock et cela devrait le faire. Utilisez le TranslateTransform uniquement si vous souhaitez animer l'élément, et même dans ce cas, il est plus pratique de le définir sur (0, 0) et de le modifier uniquement pendant l'animation.

  2. Pourquoi utilisez-vous la toile? Et plus sur pourquoi dans une grille? Vous devriez être capable de réaliser ce que vous voulez en utilisant une seule grille, ou même un DockPanel. Un canevas est utilisé uniquement pour les graphiques, qui doivent toujours rester au même endroit. Il existe de meilleures solutions pour les données, surtout si elles sont supposées changer pendant l'exécution.

Si vous voulez une croix en arrière-plan de votre réseau, vous pouvez essayer quelque chose comme ceci:

<Grid 
    Width="200" 
    Height="200" 
    Background="Beige"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*" /> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" /> 
     <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 
    <Line 
     X1="0" 
     X2="200" 
     Y1="100" 
     Y2="100" 
     Stroke="Black" 
     Grid.RowSpan="2" 
     Grid.ColumnSpan="2"/> 
    <Line 
     X1="100" 
     X2="100" 
     Y1="0" 
     Y2="200" 
     Stroke="Black" 
     Grid.RowSpan="2" 
     Grid.ColumnSpan="2"/> 
    <TextBlock 
     VerticalAlignment="Center" 
     HorizontalAlignment="Center" Margin="2" 
     Grid.Row="0" 
     Grid.Column="1"> 
     hello world1 
     <LineBreak/> 
     hello world2 
     <LineBreak/> 
     hello world3 
    </TextBlock> 
</Grid> 
+0

J'utilise un 'Canvas', avec la matrice' Translation', parce que c'est ce que je suis en train de travailler (une situation similaire à CAD). Utiliser 'Canvas.Top' et' Canvas.Left' est impossible pour moi, car les éléments ne sont pas dans un canevas (ils sont dans un 'ContentPresenter') – ManIkWeet