2013-04-01 6 views
13

Ho bisogno di un controllo pollice che può essere ridimensionato usando un mouse. Quando l'utente posiziona il mouse su una delle estremità, dovrebbe essere visualizzato un cursore di dimensione e quando l'utente fa clic e trascina la fine del controllo verrà ridimensionato.Utilizzo di WPF Sto cercando un modo per rendere ridimensionabile un controllo Thumb usando il mouse per trascinare un bordo

Ho iniziato a pensare che avrei dovuto creare un controllo personalizzato creato da tre controlli di pollice. Ci sarebbe stato un pollice principale e poi uno per ogni estremità che avrebbe gestito il ridimensionamento, ma ho deciso che non era una buona soluzione.

Sto pensando che un approccio migliore sarebbe quello di utilizzare un singolo controllo Thumb e quindi avere un popup Adorner di ridimensionamento alla fine del controllo del mouse sopra il mouse. Con questo approccio, come si rileva il passaggio del mouse su una specifica area del controllo? Esempi di come fare questo o qualsiasi aiuto sarebbe molto apprezzato.

+1

Ho usato questo campione in passato, ma è necessario fare clic sul controllo. Forse puoi adattarlo per iscriverti agli eventi di passaggio del mouse (più o più forte) http://denisvuyka.wordpress.com/2007/10/15/wpf-simple-adorner-usage-with-drag-and-resize-operations/ –

risposta

22

Ecco quello che ho fatto qualche tempo fa, permette Move e Resize, ma è possibile rimuovere la logica Move e dovrebbe funzionare bene (lo stile è ancora un po 'disordinato, ma funziona abbastanza bene)

la sua base di ContentControl in modo da poter aggiungere qualsiasi Element dentro e Sposta/Ridimensiona su un Canvas, Esso utilizza 3 Adorners, uno per il ridimensionamento, uno per Move e uno per visualizzare le informazioni (dimensioni attuali)

Ecco un esempio di lavoro completo se vuoi testare/utilizzare/modificare/migliorare :)

Codice:

namespace WpfApplication21 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 
    } 

    public class ResizeThumb : Thumb 
    { 
     public ResizeThumb() 
     { 
      DragDelta += new DragDeltaEventHandler(this.ResizeThumb_DragDelta); 
     } 

     private void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e) 
     { 
      Control designerItem = this.DataContext as Control; 

      if (designerItem != null) 
      { 
       double deltaVertical, deltaHorizontal; 

       switch (VerticalAlignment) 
       { 
        case VerticalAlignment.Bottom: 
         deltaVertical = Math.Min(-e.VerticalChange, designerItem.ActualHeight - designerItem.MinHeight); 
         designerItem.Height -= deltaVertical; 
         break; 
        case VerticalAlignment.Top: 
         deltaVertical = Math.Min(e.VerticalChange, designerItem.ActualHeight - designerItem.MinHeight); 
         Canvas.SetTop(designerItem, Canvas.GetTop(designerItem) + deltaVertical); 
         designerItem.Height -= deltaVertical; 
         break; 
        default: 
         break; 
       } 

       switch (HorizontalAlignment) 
       { 
        case HorizontalAlignment.Left: 
         deltaHorizontal = Math.Min(e.HorizontalChange, designerItem.ActualWidth - designerItem.MinWidth); 
         Canvas.SetLeft(designerItem, Canvas.GetLeft(designerItem) + deltaHorizontal); 
         designerItem.Width -= deltaHorizontal; 
         break; 
        case HorizontalAlignment.Right: 
         deltaHorizontal = Math.Min(-e.HorizontalChange, designerItem.ActualWidth - designerItem.MinWidth); 
         designerItem.Width -= deltaHorizontal; 
         break; 
        default: 
         break; 
       } 
      } 

      e.Handled = true; 
     } 
    } 


    public class MoveThumb : Thumb 
    { 
     public MoveThumb() 
     { 
      DragDelta += new DragDeltaEventHandler(this.MoveThumb_DragDelta); 
     } 

     private void MoveThumb_DragDelta(object sender, DragDeltaEventArgs e) 
     { 
      Control designerItem = this.DataContext as Control; 

      if (designerItem != null) 
      { 
       double left = Canvas.GetLeft(designerItem); 
       double top = Canvas.GetTop(designerItem); 

       Canvas.SetLeft(designerItem, left + e.HorizontalChange); 
       Canvas.SetTop(designerItem, top + e.VerticalChange); 
      } 
     } 
    } 

    public class SizeAdorner : Adorner 
    { 
     private Control chrome; 
     private VisualCollection visuals; 
     private ContentControl designerItem; 

     protected override int VisualChildrenCount 
     { 
      get 
      { 
       return this.visuals.Count; 
      } 
     } 

     public SizeAdorner(ContentControl designerItem) 
      : base(designerItem) 
     { 
      this.SnapsToDevicePixels = true; 
      this.designerItem = designerItem; 
      this.chrome = new Control(); 
      this.chrome.DataContext = designerItem; 
      this.visuals = new VisualCollection(this); 
      this.visuals.Add(this.chrome); 
     } 

     protected override Visual GetVisualChild(int index) 
     { 
      return this.visuals[index]; 
     } 

     protected override Size ArrangeOverride(Size arrangeBounds) 
     { 
      this.chrome.Arrange(new Rect(new Point(0.0, 0.0), arrangeBounds)); 
      return arrangeBounds; 
     } 
    } 
} 

Xaml:

<Window x:Class="WpfApplication21.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication21" 
     Title="MainWindow" Height="350" Width="525"> 

    <Window.Resources> 

     <Style TargetType="{x:Type ContentControl}"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type ContentControl}"> 
         <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"> 
          <local:MoveThumb Cursor="SizeAll"> 
           <local:MoveThumb.Style> 
            <Style TargetType="{x:Type local:MoveThumb}"> 
             <Setter Property="Template"> 
              <Setter.Value> 
               <ControlTemplate TargetType="{x:Type local:MoveThumb}"> 
                <Rectangle Fill="Transparent" /> 
               </ControlTemplate> 
              </Setter.Value> 
             </Setter> 
            </Style> 
           </local:MoveThumb.Style> 
          </local:MoveThumb> 
          <Control x:Name="resizer"> 
           <Control.Style> 
            <Style TargetType="{x:Type Control}"> 
             <Setter Property="Template"> 
              <Setter.Value> 
               <ControlTemplate TargetType="{x:Type Control}"> 
                <Grid> 
                 <Grid Opacity="0" Margin="-3"> 
                  <local:ResizeThumb Height="3" Cursor="SizeNS" VerticalAlignment="Top" HorizontalAlignment="Stretch"/> 
                  <local:ResizeThumb Width="3" Cursor="SizeWE" VerticalAlignment="Stretch" HorizontalAlignment="Left"/> 
                  <local:ResizeThumb Width="3" Cursor="SizeWE" VerticalAlignment="Stretch" HorizontalAlignment="Right"/> 
                  <local:ResizeThumb Height="3" Cursor="SizeNS" VerticalAlignment="Bottom" HorizontalAlignment="Stretch"/> 
                  <local:ResizeThumb Width="7" Height="7" Margin="-2" Cursor="SizeNWSE" VerticalAlignment="Top" HorizontalAlignment="Left"/> 
                  <local:ResizeThumb Width="7" Height="7" Margin="-2" Cursor="SizeNESW" VerticalAlignment="Top" HorizontalAlignment="Right"/> 
                  <local:ResizeThumb Width="7" Height="7" Margin="-2" Cursor="SizeNESW" VerticalAlignment="Bottom" HorizontalAlignment="Left"/> 
                  <local:ResizeThumb Width="7" Height="7" Margin="-2" Cursor="SizeNWSE" VerticalAlignment="Bottom" HorizontalAlignment="Right"/> 
                 </Grid> 
                 <Grid IsHitTestVisible="False" Opacity="1" Margin="-3"> 
                  <Grid.Resources> 
                   <Style TargetType="{x:Type Ellipse}"> 
                    <Setter Property="SnapsToDevicePixels" Value="true" /> 
                    <Setter Property="Stroke" Value="#FFC8C8C8" /> 
                    <Setter Property="StrokeThickness" Value=".5" /> 
                    <Setter Property="Width" Value="7" /> 
                    <Setter Property="Height" Value="7" /> 
                    <Setter Property="Margin" Value="-2" /> 
                    <Setter Property="Fill" Value="Silver" /> 
                   </Style> 
                  </Grid.Resources> 
                  <Rectangle SnapsToDevicePixels="True" StrokeThickness="1" Margin="1" Stroke="Black" StrokeDashArray="4 4"/> 
                  <Ellipse HorizontalAlignment="Left" VerticalAlignment="Top"/> 
                  <Ellipse HorizontalAlignment="Right" VerticalAlignment="Top"/> 
                  <Ellipse HorizontalAlignment="Left" VerticalAlignment="Bottom"/> 
                  <Ellipse HorizontalAlignment="Right" VerticalAlignment="Bottom"/> 
                 </Grid> 
                </Grid> 
               </ControlTemplate> 
              </Setter.Value> 
             </Setter> 
            </Style> 
           </Control.Style> 
          </Control> 
          <Grid x:Name="sizeInfo" SnapsToDevicePixels="True"> 
           <Path Stroke="Red" StrokeThickness="1" Height="10" VerticalAlignment="Bottom" Margin="-2,0,-2,-15" Stretch="Fill" Data="M0,0 0,10 M 0,5 100,5 M 100,0 100,10"/> 
           <TextBlock Text="{Binding Width}" Background="White" Padding="3,0,3,0" Foreground="Red" Margin="0,0,0,-18" HorizontalAlignment="Center" VerticalAlignment="Bottom"/> 
           <Path Stroke="Red" StrokeThickness="1" Width="10" HorizontalAlignment="Right" Margin="0,-2,-15,-2" Stretch="Fill" Data="M5,0 5,100 M 0,0 10,0 M 0,100 10,100"/> 
           <TextBlock Text="{Binding Height}" Background="White" Foreground="Red" Padding="3,0,3,0" Margin="0,0,-18,0" HorizontalAlignment="Right" VerticalAlignment="Center"> 
            <TextBlock.LayoutTransform> 
             <RotateTransform Angle="90" CenterX="1" CenterY="0.5"/> 
            </TextBlock.LayoutTransform> 
           </TextBlock> 
          </Grid> 
          <ContentPresenter Content="{TemplateBinding Content}"/> 
         </Grid> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsMouseOver" Value="True"> 
           <Setter TargetName="sizeInfo" Property="Visibility" Value="Visible" /> 
          </Trigger> 
          <Trigger Property="IsMouseOver" Value="False"> 
           <Setter TargetName="sizeInfo" Property="Visibility" Value="Hidden" /> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 

    </Window.Resources> 

    <Canvas> 
     <ContentControl Width="183" Height="110" Canvas.Left="166" Canvas.Top="50" /> 
    </Canvas> 
</Window> 

Risultato:

enter image description hereenter image description here

Con contenuto all'interno (Button)

enter image description here

Spiacente i cursori non mostrano quando si utilizza SnipTool

+1

Risposta brillante !! +1 –

+0

Grazie per il vostro aiuto. Dal tuo esempio sono riuscito a far funzionare le cose come mi serviva. – user1401827

Problemi correlati