2011-08-03 4 views
0

저는 WPF를 처음 사용합니다.WPF에서 다중 이미지 자동 조절 배경을 구현하는 방법은 무엇입니까? Android의 9 가지 패치와 비슷합니까?

두 개의 "창", 마스터 창 및 세부 창으로 분할 된 앱이 있습니다. 마스터 창은 높이가 좁고 왼쪽으로 정렬되어 있습니다. 세부 정보 창은 넓으며 대부분의 앱 영역을 차지하며 오른쪽 정렬됩니다.

여기 내 목표는 각 창의 크기가 큰 이미지 배경을 구현하는 것입니다. 이 개념은 Android의 Nine Patch () 메커니즘과 유사합니다. 사실이 WPF 앱은 동일한 앱의 Android 버전에서 사용되는 것과 동일한 소스 PNG를 사용합니다. 보시다시피이 앱은 교차 플랫폼 앱입니다. 두 플랫폼 모두에서 비즈니스 객체와 로직을 공유하지만 UI 구현은 앱이 서로 다른 부분입니다.

Nine Patch 문서를 읽을 때 을 무시합니다. 어떤 종류의보기에도 구현할 수 있습니다. 앱의 배경을 비롯하여 iOS에서 이미 작동하는 개념이 있습니다. 이제 WPF 및 Silverlight로 개념을 포팅해야합니다.

각 창의 루트 컨테이너는 System.Windows.Controls입니다. 그리드. 내가 말할 수있는 가장 좋은 방법은 그리드를 3x3 구조로 분할 한 다음 WPF 속성 바인딩을 통해 각각의 적절한 그리드 섹션에 9 개의 패치 이미지의 각 부분을 적용하는 것입니다. ImageBrush. 그러나 WPF 또는 그 바인딩 기능에 그리드를 만드는 데 완전히 익숙하지 않습니다. 그리고 창 크기 조정이 어떻게 처리 될까요?

이것에 대한 조언은 크게 감사하겠습니다. 감사.

편집 :이 경우에는 XAML을 사용할 수 없다는 점도 언급해야합니다. 이것은 모두 프로그래밍 방식으로 이루어져야합니다.

편집 : loxxy의 충고를 잘 보여주고 다음 단계에 대한 추가 안내를 원합니다. 여기에 지금까지 내 구현 결과이다 (I 등등 읽어 보시기 바랍니다 아래의 질문이) :

Nine Patch for WPF NOW

NinePatchImage npi = new NinePatchImage([some params]); 
Grid backgroundGrid = new Grid(); 
backgroundGrid.ColumnDefinitions.Clear(); 
backgroundGrid.RowDefinitions.Clear(); 
backgroundGrid.ColumnDefinitions.Add(
    // first column 
    new ColumnDefinition() 
    { 
     Width = new GridLength(1, GridUnitType.Auto), 
    }); 
backgroundGrid.ColumnDefinitions.Add(
    // second column 
    new ColumnDefinition() 
    { 
     Width = new GridLength(1, GridUnitType.Star) 
    }); 
backgroundGrid.ColumnDefinitions.Add(
    // third column 
    new ColumnDefinition() 
    { 
     Width = new GridLength(1, GridUnitType.Auto) 
    }); 
backgroundGrid.RowDefinitions.Add(
    // first row 
    new RowDefinition() 
    { 
     Height = new GridLength(1, GridUnitType.Auto), 
    }); 
backgroundGrid.RowDefinitions.Add(
    // second row 
    new RowDefinition() 
    { 
     Height = new GridLength(1, GridUnitType.Star) 
    }); 
backgroundGrid.RowDefinitions.Add(
    // third row 
    new RowDefinition() 
    { 
     Height = new GridLength(1, GridUnitType.Auto) 
    }); 

var imageTopLeft = new Image() { Source = (npi.TopLeft != null) ? npi.TopLeft : null, Stretch = Stretch.None }; 
var imageTopCenter = new Image() { Source = (npi.TopCenter != null) ? npi.TopCenter : null, Stretch = Stretch.None }; 
var imageTopRight = new Image() { Source = (npi.TopRight != null) ? npi.TopRight : null, Stretch = Stretch.None }; 
var imageMiddleLeft = new Image() { Source = (npi.MiddleLeft != null) ? npi.MiddleLeft : null, Stretch = Stretch.None }; 
var imageMiddleCenter = new Image() { Source = (npi.MiddleCenter != null) ? npi.MiddleCenter : null, Stretch = Stretch.None }; 
var imageMiddleRight = new Image() { Source = (npi.MiddleRight != null) ? npi.MiddleRight : null, Stretch = Stretch.None }; 
var imageBottomLeft = new Image() { Source = (npi.BottomLeft != null) ? npi.BottomLeft : null, Stretch = Stretch.None }; 
var imageBottomCenter = new Image() { Source = (npi.BottomCenter != null) ? npi.BottomCenter : null, Stretch = Stretch.None }; 
var imageBottomRight = new Image() { Source = (npi.BottomRight != null) ? npi.BottomRight : null, Stretch = Stretch.None }; 

backgroundGrid.Children.Add(imageTopLeft); Grid.SetColumn(imageTopLeft, 0); Grid.SetRow(imageTopLeft, 0); 
backgroundGrid.Children.Add(imageTopCenter); Grid.SetColumn(imageTopCenter, 1); Grid.SetRow(imageTopCenter, 0); 
backgroundGrid.Children.Add(imageTopRight); Grid.SetColumn(imageTopRight, 2); Grid.SetRow(imageTopRight, 0); 
backgroundGrid.Children.Add(imageMiddleLeft); Grid.SetColumn(imageMiddleLeft, 0); Grid.SetRow(imageMiddleLeft, 1); 
backgroundGrid.Children.Add(imageMiddleCenter); Grid.SetColumn(imageMiddleCenter, 1); Grid.SetRow(imageMiddleCenter, 1); 
backgroundGrid.Children.Add(imageMiddleRight); Grid.SetColumn(imageMiddleRight, 2); Grid.SetRow(imageMiddleRight, 1); 
backgroundGrid.Children.Add(imageBottomLeft); Grid.SetColumn(imageBottomLeft, 0); Grid.SetRow(imageBottomLeft, 2); 
backgroundGrid.Children.Add(imageBottomCenter); Grid.SetColumn(imageBottomCenter, 1); Grid.SetRow(imageBottomCenter, 2); 
backgroundGrid.Children.Add(imageBottomRight); Grid.SetColumn(imageBottomRight, 2); Grid.SetRow(imageBottomRight, 2); 

Grid contentArea = new Grid() { ColumnDefinitions = { new ColumnDefinition() } }; 
// setup contentArea here blah blah blah 

// a containing grid 
Grid container = new Grid(); 
// add the background grid to the containing grid 
container.Children.Add(backgroundGrid); 
// add the content grid to the background grid's UIElement collection 
backgroundGrid.Children.Add(contentArea); 
// set the backgroundGrid's column position 
Grid.SetColumn(backgroundGrid, 0); 
// set the backgroundGrid's row position 
Grid.SetRow(backgroundGrid, 0); 
// set the content area's column position 
Grid.SetColumn(contentArea, 1); 
// set the content area's row position 
Grid.SetRow(contentArea, 1); 

, 나는 상단과 측면 이미지가 올바른 방향으로 늘리거나 타일을 얻을 필요 , x 또는 y. 이미지 WPF 요소에는 여러 옵션이있는 스트레치 속성이 있지만 x 및 y 방향 모두에서 스트레치가 발생하지만 두 치수 중 하나만 스트레칭해야합니다. 또한 필요한 경우 (위의 이미지와 마찬가지로) x 또는 y에서 TILE을 수행 할 수 있어야합니다. image 요소는 이것을 지원하지 않지만 ImageBrush 클래스는 이러한 종류의 것들에 매우 유용 할 수 있습니다. ImageBrush를 Image 요소 나 다른 유형의 요소에 직접 바인딩 할 수 있습니까 ??

+0

로 바인딩의 컨버터를 구현 : – NovaJoe

+0

그냥 나는이 모든 정리 가지고 언급하고 싶었다. 좋은 작품! – NovaJoe

답변

2

두 개의 창이 (원하는대로) 필요한 경우 왜 3x3 격자가 필요하다고 생각합니까? 배경에 대한 단순한 것이라면 ImageBrush은 두 패널을 다르게 칠하기에 충분합니다.

또한 패널을 오른쪽, 왼쪽으로 정렬하는 것과 관련하여 이야기 할 때는 DockPanel을 선호합니다. 독 패널의 마지막 자식은 부모 컨테이너를 채우기 위해 늘어납니다.

바인딩을 사용하여 작업하려는 부분을 얻지 못했습니다.패널 안의 내용을 바인딩하는 것에 대해 이야기하고 있습니까? 아니면 배경 이미지를 원본과 바인딩하려고합니까?


아홉 개의 다른 이미지와 관련된 9 개의 패치를 찾을 수는 없지만 ninepatch 문서를 읽었습니다. 느꼈던 nine 패치은 단순히 테두리가있는 신축성있는 이미지입니다.

어쨌든 9 개의 이미지를 배경으로 사용하려는 경우 하위 격자 내에서 이미지를 사용할 수 있습니다. 동일한 행과 열에있는 격자에 여러 내용을 넣으면 마지막 자식이 격자의 최상위 계층을 차지합니다.

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

       <Image Source="Img1.png" Grid.Row="0" Grid.Column="0"/> 
       <Image Source="Img2.png" Grid.Row="0" Grid.Column="1"/> 
       <Image Source="Img3.png" Grid.Row="0" Grid.Column="2"/> 
       <Image Source="Img4.png" Grid.Row="1" Grid.Column="0"/> 
       <Image Source="Img5.png" Grid.Row="1" Grid.Column="1"/> 
       <Image Source="Img6.png" Grid.Row="1" Grid.Column="2"/> 
       <Image Source="Img7.png" Grid.Row="2" Grid.Column="0"/> 
       <Image Source="Img8.png" Grid.Row="2" Grid.Column="1"/> 
       <Image Source="Img9.png" Grid.Row="2" Grid.Column="2"/> 
      </Grid> 

      <Grid> 
       <Label>This Content is put in front.</Label> 
      </Grid> 
</Grid> 

이제 바인딩 부분. 이미지 소스를 동적으로 업데이트 하시겠습니까? 나는 9 개의 이미지로 이미지 소스를 변경한다는 것을 의미합니까 ?? 그런 다음 바인딩 만 필요합니다. 그것은 단순히 소스 일 경우 왜 URI를 직접 지정하지 마십시오.

하지만 당신이 정말로 필요로하는 경우 바인딩, ImagePath를 문자열입니다

<Image Source="{Binding ImagePath}" /> 

. 이것은 이미지 소스를 문자열로 지정할 수있는 내장 변환기를 사용합니다.

그러나 실버 라이트 바인딩에서 문제를 피하기 위해 자신의 변환기를 사용할 수 있습니다.

public sealed class ImageConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, 
          object parameter, CultureInfo culture) 
    { 
     try 
     { 
      return new BitmapImage(new Uri((string)value)); 
     } 
     catch 
     { 
      return new BitmapImage(); 
     } 
    } 

    public object ConvertBack(object value, Type targetType, 
           object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

는 모든 데이터는 더미 데이터이며, BTW

<Image Source="{Binding Path=ImagePath, Converter=...}" /> 
+0

각 창은 전체 레이아웃의 3x3이 아니라 3x3입니다. 이것을 단순화합시다. 두 창 개념을 무시하십시오. 하나의 창을 살펴 봅시다. RadDockPanel을 주 컨테이너로 사용하고 있습니다. 네, 9 개의 패치 이미지 각각에 대해 하나씩 소스 이미지에 배경 이미지를 바인딩하려고합니다. Nine Patch 문서를 읽었습니까? – NovaJoe

+0

수정 사항을 참조하십시오. – loxxy

+0

뛰어난! 감사! XAML을 사용하지는 않지만 API를 사용하여 C#을 사용하여이 모든 것을 적용하기는 쉽습니다. 내가받은 최고의 답변 중 하나. 9 개의 패치/이미지 소스에 관한 질문 : NinePatch 클래스는 생성자에서 PNG를 사용합니다. 이미지는 슬라이스되어 건축시에 깎여지며 9 개의 부분이 프라이빗 vars에 보관됩니다. 이 클래스에는 9 개의 파트 각각에 대한 인스턴스 getter 메서드도 있습니다. 그래서 NinePatch 인스턴스에 바인딩하고, 값 변환기를 사용하고, 필요에 따라 적절한 부분을 가져옵니다. 이를 통해 여러 플랫폼에서 동일한 파일을 사용할 수 있습니다. – NovaJoe

관련 문제