2012-09-28 7 views
8

이 코드 숨김에서 할 매우 쉽습니다 :WPF 컨트롤의 여백 속성의 오른쪽 (또는 왼쪽, 위, 아래) 값만 수정하면됩니까?

var button = new Button(); 
var margin = button.Margin; 
margin.Right = 10; 
button.Margin = margin; 

는 XAML 그러나, 나는 다음에 제한된 해요 :

<Button Margin="0,0,10,0" /> 

이 문제는 지금이된다는 것입니다 잠재적으로 다른 여백 값 (예 : 왼쪽, 위, 아래)을 0으로 설정하여 덮어 씁니다.

다음과 같은 방법으로 XAML을 사용할 수 있습니까?

<Button MarginRight="10" /> 

답변

7

첨부 된 속성을 사용할 수 있습니다. 사실 이것은 연결된 속성의 목적입니다. 부모 요소 속성에 액세스하거나 특정 요소에 추가 기능을 추가하는 것입니다.

using System; 
using System.Windows; 
using System.Windows.Controls; 

namespace YourApp.AttachedProperties 
{ 
    public class MoreProps 
    { 
     public static readonly DependencyProperty MarginRightProperty = DependencyProperty.RegisterAttached(
      "MarginRight", 
      typeof(string), 
      typeof(MoreProps), 
      new UIPropertyMetadata(OnMarginRightPropertyChanged)); 

     public static string GetMarginRight(FrameworkElement element) 
     { 
      return (string)element.GetValue(MarginRightProperty); 
     } 

     public static void SetMarginRight(FrameworkElement element, string value) 
     { 
      element.SetValue(MarginRightProperty, value); 
     } 

     private static void OnMarginRightPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
     { 
      var element = obj as FrameworkElement; 

      if (element != null) 
      { 
       int value; 
       if (Int32.TryParse((string)args.NewValue, out value)) 
       { 
        var margin = element.Margin; 
        margin.Right = value; 
        element.Margin = margin; 
       } 
      } 
     } 
    } 
} 

은 이제 XAML에서 당신이해야 할 일은 다음 네임 스페이스 선언입니다 :

예를 들어, 응용 프로그램에서 어딘가에 다음과 같은 클래스를 정의

xmlns:ap="clr-namespace:YourApp.AttachedProperties" 

을 그리고 당신은 XAML을 쓸 수 있습니다 예를 들면 다음과 같습니다 :

<Button ap:MoreProps.MarginRight="10" /> 



다른 방법으로는 연결된 속성을 사용하여 피할 수 대신 같은 일부 약간 더 긴 XAML 쓰기 :

<Button>
        <Button.Margin>
                <Thickness Right="10" />
        </Button.Margin>
</Button>

+3

가 마지막에 XAML은 마진 = "0,0,10,0"'당신이 덮어 쓰기로 기존의'Thickness' 경우'과 같은 일을하는지가 하나입니다. –

+1

@ H.B. 고마워, 나는 그 마지막 부분을 테스트 했어야했다. 네가 옳아. 전체 마진이 재 할당되고 지정되지 않은 값은 기본값으로 반환됩니다. 나는 그 부분에 대한 답변을 편집했습니다. – bugged87

0

당신은이 부분에 잘못 :

var button = new Button(); 
button.Margin.Right = 10; 

에로 r에 CS1612은 : 여백이 struct를 반환하고, 따라서 값 형식이기 때문에 변수

는 이미 유효하지 않은 코드가 아니기 때문에 'System.Windows.FrameworkElement.Margin'의 반환 값을 수정할 수 없습니다. DependencyObject에서 파생되지 않기 때문에 많은 데이터 바인딩 트릭도 작동하지 않습니다.

나는 적절한 설명을하고 싶었지만, 그렇지 않다면 첫 번째 대답은 거의 유일한 길이라고 말할 수 있습니다.

+0

@ dowhilefor 코드 숨김 부분이 맞습니다. 내 잘못 입력. 내가 실제로 의미했던 것을 반영하도록 내 질문을 업데이트했습니다. 그러나 MarginRight 속성이 DependencyObject이므로 DataBinding이 작동합니다. 따라서 바인딩을 통해 속성 값이 변경 될 때마다 콜백 메서드에 따라 여백이 조정됩니다. – bugged87

+0

@ bugged87 데이터 바인딩의 의미는 첨부 된 속성 대답이 아니라 원래 질문이었습니다. 물론 데이터 바인딩이 작동합니다. 그러나 Thickness가있는 구조체의 경우 소스가 아니라면 데이터 바인딩을 사용할 수 없습니다. 간단히 말해서 나는 마진 라이트 (MarginRight)에 대해 말한 것이 아니라 마진 (Margin)에 대해 말하고있었습니다. 맞아요. – dowhilefor

1

attatched 속성이 작동 할 수 있지만. 나는 당신의 코드를 리팩터링하려고 노력할 것이므로 코드의 UI 변경을하지 않을 것이다. 파일의 디자인 측면에서 가능한 한 많은 UI를 처리해야합니다. xaml 파일의 코드 숨김을 가능한 한 적게 사용하려고합니다. MVVM에서 문제가 발생하기 때문입니다.

+1

코드 리팩터링에 대한 제안 사항이 있습니까? XAML 디자이너가 필요한 기능이 부족하면 코드 숨김 기능이 추가 기능을 추가하기에 좋은 곳인 것처럼 보입니다. 한 곳에서 정의되고 유지 관리되는 연결된 속성은 각 XAML 파일의 코드 숨김에 코드를 작성하는 것과 실제로 같지 않습니다. 나는 또한 당신이 코드 숨김에서 무엇을하고 있는지에 달려 있다고 생각한다. 데이터 컨텍스트를 수정하는 경우 MVVM 패턴에 문제가 발생할 수 있습니다. 그러나 UI 구성 요소 만 수정하는 중이라면 괜찮을 것입니다. – bugged87

+0

이 문제는 항상 문제가 있습니다 ... 코드 숨김은 XAML 코드가있는 부분 클래스입니다. XAML과 같은 수준입니다. UI 관련 작업 만 수행하는 데 사용할 수 있다면 XAML에서 수행하는 것과 다를 바 없습니다. – AshbyEngineer

1

MVVM의 속성 (문자열)에 대한 여백을 데이터 바인딩 할 수 있습니다. MVVM에서 필요한 것은 개별 속성 (위, 오른쪽, 아래, 오른쪽)을 추적하는 것입니다.

당신은 같이 컨버터를 사용할 수 있습니다 How to set a top margin only in XAML? 또는 Binding only part of the margin property of WPF control

+0

내 뷰 모델의 속성에 대한 데이터 바인딩은 내 뷰 모델이 UI 디자인과 관련된 값을 유지해야한다는 것을 의미합니다. 이렇게하면 MVVM 패턴이 손상됩니다. – bugged87

+0

전적으로 당신과 동의합니다 ... "UI"특정 기능 (예 : 상태에 따라 행을 채색하는 것) 사이에 선을 그어야합니다. "로직"이 관련되어 있고 코드가 서비스 결과 및/또는 속성과 같은 "기타"속성에 의존하는 경우 MVVM은 ... 또는 항상 비헤이비어를 첨부 할 수 있습니다. –

관련 문제