0

現在のページを変更するときにタブバーを複数のページに配置する必要があるため、ユーザーコントロールを使用してタブバーを作成しました。これは、正しい画像の後ろに暗い矩形を移動して、現在表示されているページをタブバーに表示する必要があることを意味します。そこで、SelectionIndexというカスタムプロパティを使用して、正しいイメージの背後に選択矩形を移動しようとしました.0はホームイメージ、1はスケジュールイメージなどです。下のコードは、選択したイメージが表示されるページで使用されているタブバーを示しています2番目のもの。カスタムプロパティのリテラル値が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です。

私はこの問題をGoogledしていますが、他の誰かが問題を抱えているようです。プロパティに値をバインドして、XAMLで0〜5の整数にプロパティを設定できます。

+0

TabBarコンストラクターの後にSelectionIndex値が設定されているようです。スイッチを別の場所に移動しようとすると、「ロードされました」たとえば –

+0

@AlekDeplerうまくいきました。答えとして投稿して受け入れることができますか?ありがとう、 –

+0

@RossTinsleyはLoadedを使用しません。値が最初に設定された後に値が変更されても機能しません。 –

答えて

-3

SelectionIndex値がTabBarののconstrustor後に設定されているようです:私たちは、デフォルト値-1、それ以外の場合はプロパティ変更ハンドラーがこれまで呼び出されませんを行います。スイッチを別の場所に移動しようとします。たとえば、「ロード済み」:

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

このソリューションは、プロパティの値が1回だけ設定されている場合に機能します。代わりに、予想される動作に沿ってプロパティの変更を処理する必要があります。 –

+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

は、それはゼロだ、nullではありません。

しかし、おおまかに言えば、属性はコンストラクターが完了するまで割り当てられないということです。より広義には、WPFがあなたにできることを利用する方法を利用していません。

WPFでは、これは多くのC#コードなしで行うことができます。位置決めにマージンを使用しないで、グリッドを使用してください。 Grid.ColumnプロパティをSelectedIndexにバインドして、グリッド内に「マーカー」境界線を配置します。可能な限りシンプルで、グリッド内のアイテムのサイズを変更することができ、すべてが魔法のように機能します。 3列目に2つのものを入れたいのであれば、 "これを356単位オフセットにする"ではなく、 "これを3列目に置く"と言った方が良いでしょう。再び3列目のオフセット?それで、来年はデザインを変更し、そのうちの1つを更新することを忘れてしまいます。

<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> 

しかし

あなたの独創的なアプローチに固執したい場合は、Loadedイベントにその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; 
    } 
} 
関連する問題