2009-06-02 3 views
1

WPF 및 VB.Net에서 Flex/Flash의 9 슬라이스 기능을 복제하는 방법을 알고 있는지 궁금합니다. Flex에서 여러 번 9 슬라이스 크기 조절을 사용 했으므로 WPF에서 큰 자산이됩니다. 저는 Canvas의 배경으로 이미지를 가질 수 있고 둥근 모서리를 망가지지 않고 이미지를 늘릴 수 있기를 바랍니다. 제발, 아무도 이것을하는 방법을 알고 있습니까?9-Slice Images in WPF

답변

1

이 작업을 수행 할 수있는 기본 제공 기능을 알지 못합니다. 그러나 이렇게 할 수있는 사용자 지정 컨트롤을 작성할 수 있습니다.

이러한 컨트롤의 중요한 부분은 4 부분이 고정 된 크기 (모서리), 2 부분이 고정 된 높이와 다양한 너비 (중앙 상단 및 중앙 하단)가있는 9 부분 격자이고, 두 부분은 고정되어 있습니다 너비와 변수 높이 (왼쪽 중앙과 오른쪽 중심), 마지막 부분은 가변 높이와 너비 (중간)를가집니다. 한 방향으로 만 스트레칭 (예 : 수평으로 자라는 버튼 만들기)은 중간 부분의 높이를 제한하는 것만 큼 간단합니다.

XAML에서, 그는 다음과 같습니다

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="20"/> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="20"/> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="20"/> 
     <RowDefinition Height="*"/> 
     <RowDefinition Height="20"/> 
    </Grid.RowDefinitions> 
</Grid> 

는 그런 다음에 내용을 넣어 객체뿐만 아니라, (나는 사각형을 사용합니다)에의 이미지를 페인트 (ContentPresenter에)를 개체를 추가 할 것

<Rectangle> 
    <Rectangle.Fill> 
     <ImageBrush ImageSource="Image.png" TileMode="None" 
        <!-- Add the settings necessary to show the correct part of the image --> /> 
    </Rectangle.Fill> 
</Rectangle> 
: 그들이 당신의 소스 이미지의 정확한 부분을 보여줄 수 있도록
<Rectangle Grid.Row="0" Grid.Column="0" x:Name="TopLeft"/> 
<Rectangle Grid.Row="0" Grid.Column="1" x:Name="TopCenter"/> 
<Rectangle Grid.Row="0" Grid.Column="2" x:Name="TopRight"/> 

<Rectangle Grid.Row="1" Grid.Column="0" x:Name="CenterLeft"/> 
<Rectangle Grid.Row="1" Grid.Column="2" x:Name="CenterRight"/> 

<Rectangle Grid.Row="2" Grid.Column="0" x:Name="BottomLeft"/> 
<Rectangle Grid.Row="2" Grid.Column="1" x:Name="BottomCenter"/> 
<Rectangle Grid.Row="2" Grid.Column="2" x:Name="BottomRight"/> 

<Grid Grid.Row="2" Grid.Column="1" x:Name="Middle"> 
    <Rectangle/> 
    <ContentPresenter x:Name="MiddleContent"/> 
</Grid> 

사각형의 각

은 ImageBrush와를 사용하여 페인트 할 수 있습니다 사용자 지정 컨트롤로 그 모든을 포장

, 당신은 꽤 가능한 9 슬라이스 이미지 컨트롤을 생성 할 수 있습니다 : 당신이 그것을 사용할 수 있도록 슬라이스를 입력 System.Windows.Size의 속성이다

<local:NineSliceImage Image="Source.png" Slice="20,20"> 
    <TextBox Text="Nine Slice Image TextBox!"/> 
</local:NineSliceImage> 

여백/여백/등. 조각의 위치를 ​​설정하는 속성

또한 모든 사각형에서 SnapToDisplayPixels를 True로 설정하려고합니다. 그렇지 않으면 WPF가 중간 픽셀을 보간하려고 할 때 특정 해상도에서 이미지 조각 사이에 작은 간격이 표시됩니다.

이러한 컨트롤을 많이 사용하려는 경우 약간 빠른 방법은 OnRender를 재정의하고 거기에서 수행하는 것입니다. 나는 3 슬라이스 이미지 컨트롤을 위해 이것을 한 적이 있지만 꽤 까다 롭습니다.

그 방법으로 당신을 얻을 수 있어야합니다. 제가 누락 된 것이 있으면, 의견을 남겨주세요.

2

다음은 내가 수고를 끝내고 끝낸 것입니다.

이것은 SlicedImage입니다.XAML 파일 :

,
<Rectangle Grid.Row="1" Grid.Column="0" SnapsToDevicePixels="True"> 
     <Rectangle.Fill> 
      <ImageBrush x:Name="CenterLeft" Stretch="Fill" ViewboxUnits="Absolute" AlignmentX="Left" AlignmentY="Center" /> 
     </Rectangle.Fill> 
    </Rectangle> 
    <Rectangle Grid.Row="1" Grid.Column="1" SnapsToDevicePixels="True"> 
     <Rectangle.Fill> 
      <ImageBrush x:Name="CenterCenter" Stretch="Fill" ViewboxUnits="Absolute" AlignmentX="Center" AlignmentY="Center" /> 
     </Rectangle.Fill> 
    </Rectangle> 
    <Rectangle Grid.Row="1" Grid.Column="2" SnapsToDevicePixels="True"> 
     <Rectangle.Fill> 
      <ImageBrush x:Name="CenterRight" Stretch="Fill" ViewboxUnits="Absolute" AlignmentX="Right" AlignmentY="Center" /> 
     </Rectangle.Fill> 
    </Rectangle> 

    <Rectangle Grid.Row="2" Grid.Column="0" SnapsToDevicePixels="True"> 
     <Rectangle.Fill> 
      <ImageBrush x:Name="BottomLeft" Stretch="Fill" ViewboxUnits="Absolute" AlignmentX="Left" AlignmentY="Bottom" /> 
     </Rectangle.Fill> 
    </Rectangle> 
    <Rectangle Grid.Row="2" Grid.Column="1" SnapsToDevicePixels="True"> 
     <Rectangle.Fill> 
      <ImageBrush x:Name="BottomCenter" Stretch="Fill" ViewboxUnits="Absolute" AlignmentX="Center" AlignmentY="Bottom" /> 
     </Rectangle.Fill> 
    </Rectangle> 
    <Rectangle Grid.Row="2" Grid.Column="2" SnapsToDevicePixels="True"> 
     <Rectangle.Fill> 
      <ImageBrush x:Name="BottomRight" Stretch="Fill" ViewboxUnits="Absolute" AlignmentX="Right" AlignmentY="Bottom" /> 
     </Rectangle.Fill> 
    </Rectangle> 

</Grid> 

</UserControl> 

그리고 VB.Net이 원하는 사람들을위한 SlicedImage.xaml.vb :

Partial Public Class SlicedImage 
Public imageSource As ImageSource 
Public sliceTop As Double 
Public sliceRight As Double 
Public sliceLeft As Double 
Public sliceBottom As Double 

Public Sub New() 

    InitializeComponent() 

End Sub 

Public Sub SetViewboxes() 
    Dim RealHeight As Double = TopLeft.ImageSource.Height 
    Dim RealWidth As Double = TopLeft.ImageSource.Width 

    ColumnLeft.Width = New GridLength(sliceLeft) 
    ColumnRight.Width = New GridLength(RealWidth - sliceRight) 
    RowTop.Height = New GridLength(sliceTop) 
    RowBottom.Height = New GridLength(RealHeight - sliceBottom) 


    TopLeft.Viewbox = New Rect(0, 0, sliceLeft, sliceTop) 
    TopCenter.Viewbox = New Rect(sliceLeft, 0, sliceRight - sliceLeft, sliceTop) 
    TopRight.Viewbox = New Rect(sliceRight, 0, RealWidth - sliceRight, sliceTop) 

    CenterLeft.Viewbox = New Rect(0, sliceTop, sliceLeft, sliceBottom - sliceTop) 
    CenterCenter.Viewbox = New Rect(sliceLeft, sliceTop, sliceRight - sliceLeft, sliceBottom - sliceTop) 
    CenterRight.Viewbox = New Rect(sliceRight, sliceTop, RealWidth - sliceRight, sliceBottom - sliceTop) 

    BottomLeft.Viewbox = New Rect(0, sliceBottom, sliceLeft, RealHeight - sliceBottom) 
    BottomCenter.Viewbox = New Rect(sliceLeft, sliceBottom, sliceRight - sliceLeft, RealHeight - sliceBottom) 
    BottomRight.Viewbox = New Rect(sliceRight, sliceBottom, RealWidth - sliceRight, RealHeight - sliceBottom) 

End Sub 
Public Property ImageLocation() As ImageSource 
    Get 
     Return Nothing 
    End Get 
    Set(ByVal value As ImageSource) 
     TopLeft.ImageSource = value 
     TopCenter.ImageSource = value 
     TopRight.ImageSource = value 
     CenterLeft.ImageSource = value 
     CenterCenter.ImageSource = value 
     CenterRight.ImageSource = value 
     BottomLeft.ImageSource = value 
     BottomCenter.ImageSource = value 
     BottomRight.ImageSource = value 
    End Set 
End Property 

Public Property Slices() As String 
    Get 
     Return Nothing 
    End Get 
    Set(ByVal value As String) 
     Dim sliceArray As Array = value.Split(" ") 
     sliceTop = sliceArray(0) 
     sliceRight = sliceArray(1) 
     sliceBottom = sliceArray(2) 
     sliceLeft = sliceArray(3) 
     SetViewboxes() 
    End Set 
End Property 

End Class 

사용자 정의 컨트롤은 다음과 같이 사용됩니다 :

는 ImageLocation는
<my:SlicedImage ImageLocation="Images/left_bubble.png" Slices="18 25 19 24" /> 

입니다 이미지 위치 및 슬라이스는 이미지를 슬라이스하는 방법에 대한 "오른쪽 위 왼쪽 하단"입니다. 모든 치수는 왼쪽 상단 모서리를 기반으로해야합니다.

+0

C#에서 내 자신의 사용자 지정 컨트롤을 롤링 한 후이를 알게되었습니다. :-) http://wldevries.wordpress.com/2014/06/08/image-ninegrid-for-wpf/ – Wouter