0

사용자 정의 컨트롤을 사용하여 탭 막대를 만들었습니다. 탭 막대가 현재 페이지를 변경할 때 여러 페이지에 있어야하기 때문입니다. 즉, 탭 바는 올바른 이미지 뒤에 어두운 사각형을 이동하여 현재 표시된 페이지를 표시해야합니다. 그래서 SelectionIndex라는 사용자 정의 속성을 사용하여 올바른 이미지 뒤에 선택 사각형을 옮겨 보았습니다. 홈 이미지는 0이고 일정 이미지는 1입니다. 아래 코드는 선택된 이미지가 있어야하는 페이지에서 사용되는 탭 막대를 보여줍니다 두 번째 것.사용자 지정 속성의 리터럴 값이 null입니다.

<Grid> 
     <local:TabBar SelectionIndex="1" Margin="0,0,1222,0"/> 
    </Grid> 

아래 코드 propdp 의해 생성 한 난 SelectionIndex에 속성의 이름을 바꾸었다. 그런 다음 Switch-Case를 사용하여 속성의 값을 확인하고 사각형 이미지의 여백을 변경하여 이동합니다.

public partial class TabBar : UserControl 
{ 
    public int SelectionIndex 
    { 
     get { return (int)GetValue(SelectionIndexProperty); } 
     set { SetValue(SelectionIndexProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for SelectionIndex. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty SelectionIndexProperty = 
     DependencyProperty.Register("SelectionIndex", typeof(int), typeof(TabBar), new PropertyMetadata(0)); 


    public TabBar() 
    { 
     InitializeComponent(); 

     switch (SelectionIndex) 
     { 
      case 0: 
       SelectionBox.Margin = new Thickness(0, 10, 0, 0); 
       break; 
      case 1: 
       SelectionBox.Margin = new Thickness(0, 123, 0, 0); 
       break; 
     } 
    } 
} 

그러나, 나는 그것이 0했지만이에게 자신을 해결하기 위해 1. 을해야한다, SelectionIndex의 값을 확인 switch (SelectionIndex)에 브레이크 포인트를 넣어, 나는에서 문자열로 속성 유형을 변경 한 int, 이것은 SelectionIndex가 "0"이 아니라는 것을 보여 주며, null입니다.

저는이 문제를 인터넷 검색으로 해결했지만 다른 모든 사용자가 문제를 겪고있는 것처럼 보입니다. 속성에 값을 바인딩하는 경우 XAML에서 0-5 사이의 int로 속성을 설정할 수 있기를 원합니다.

+0

TabBar 지정자 다음에 SelectionIndex 값이 설정된 것으로 보입니다. 스위치를 다른 장소로 옮기십시오. "로드 됨"(예 : –

+0

) @AlekDepler 성공 했으므로 답변으로 게시하여 받아 들일 수 있습니까? 고마워요, –

+0

@RossTinsley는 Loaded를 사용하지 않습니다. 처음 설정 한 후에 값이 변경되면 작동하지 않습니다. –

답변

-3

SelectionIndex 값이 TabBar의의 construstor 후 설정 보인다 : 우리는 디폴트 값 -1, 그렇지 않으면 속성 변경 처리기 적 호출되지 않습니다를 만들 수 있습니다.스위치를 다른 장소로 이동하려고하면 다음과 같이로드됩니다.

private void TabBar_Loaded(object sender, RoutedEventArgs e) 
{ 
    //... 
} 
+0

이 솔루션은 속성의 값을 한 번만 설정하면 작동합니다. 예상되는 동작에 더 가까워지기 때문에 대신 속성의 변경을 처리해야합니다. –

+0

@ TitianCernicova-Dragomir 그는 재산 변경을 처리 할 필요가 없다고 말했다. –

+2

@AaronChristiansen "완전히 실패하지 않는 최악의 해결책"은 일반적인 설계 원칙이지만 아주 좋은 해결책은 아닙니다. –

1

문제는 생성자에서이 작업을 수행하고 컨트롤을 만든 후에 값이 속성에 설정되어 있다는 것입니다.

public partial class TabBar : UserControl 
{ 
    .... 
    // Using a DependencyProperty as the backing store for SelectionIndex. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty SelectionIndexProperty = 
     DependencyProperty.Register("SelectionIndex", typeof(int), typeof(TabBar), new PropertyMetadata(0, propertyChangedCallback: (d,e)=> ((TabBar)d).OnSelectionIndexChanged())); 


    public void OnSelectionIndexChanged() 
    { 
     switch (SelectionIndex) 
     { 
      // .... 
     } 
    } 
} 
1

그것은, 그것은 0이 아닌 널 (null)의 것 :

당신은 변화를 처리하는 종속성 속성에 속성 변경 처리기를 추가하고, 메소드를 호출 할 필요가있다.

하지만 좁게 말하면 속성은 생성자가 완료 될 때까지 할당되지 않는다는 것입니다. 더 광범위하게 WPF가 당신이 일을 할 수있게하는 방식을 이용하지 않습니다.

WPF에서는 많은 C# 코드없이이 작업을 수행 할 수 있습니다. 위치 지정에 여백을 사용하지 마십시오. 그리드를 사용하십시오. Grid.Column 속성을 SelectedIndex으로 바인딩하여 표식 안에 경계선을 배치합니다. 간단하고 그리드의 항목 크기를 조절할 수 있으므로 모든 것이 마술처럼 작동합니다. 3 열에 2 가지를 넣고 싶다면 "이것을 356 단위로 나누기"보다는 "열 3에 넣으십시오"라고 말하면 좋을 것입니다. 그리고 다른 말로는 "어 ... 이걸 넣으세요. 3 열의 오프셋이 다시 나타 납니까? " 그런 다음 내년에 디자인을 변경하고 그 중 하나를 업데이트하는 것을 잊어 버립니다. 당신이 당신의 원래의 접근 방식을 고수하고 싶었다면

<Grid> 
    <Grid.ColumnDefinitions> 
     <!-- Made up width values --> 
     <ColumnDefinition Width="100" /> 
     <ColumnDefinition Width="100" /> 
     <ColumnDefinition Width="100" /> 
     <ColumnDefinition Width="100" /> 
    </Grid.ColumnDefinitions> 
    <Border 
     Background="DeepSkyBlue" 
     Grid.Column="{Binding SelectionIndex, RelativeSource={RelativeSource AncestorType=UserControl}}" 
     > 
    </Border> 
    <Label Grid.Column="0">Click Me</Label> 
    <Label Grid.Column="1">No, Click Me</Label> 
    <Label Grid.Column="2">Me Me Me!</Label> 
    <Label Grid.Column="3">Wahhhh</Label> 
</Grid> 

그러나

, 당신은로드 이벤트에 그 switch 문을 움직일 수 있지만, "더 나은"방법은 함께 할 할 의존성 프로퍼티의 PropertyChanged 핸들러. 이렇게하면 속성이 변경 될 때마다 컨트롤이 변경 사항에 적절하게 응답합니다.

public int SelectionIndex 
{ 
    get { return (int)GetValue(SelectionIndexProperty); } 
    set { SetValue(SelectionIndexProperty, value); } 
} 

public static readonly DependencyProperty SelectionIndexProperty = 
    DependencyProperty.Register(nameof(SelectionIndex), typeof(int), typeof(TabBar), 
     new FrameworkPropertyMetadata(-1, SelectionIndex_PropertyChanged)); 

protected static void SelectionIndex_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    (d as TabBar).OnSelectionIndexChanged(e.OldValue); 
} 

private void OnSelectionIndexChanged(object oldValue) 
{ 
    switch (SelectionIndex) 
    { 
     case 0: 
      SelectionBox.Margin = new Thickness(0, 10, 0, 0); 
      break; 
     case 1: 
      SelectionBox.Margin = new Thickness(0, 123, 0, 0); 
      break; 
    } 
}