2016-05-23 9 views
0

注:UserControlの他の同様の記事のようにユーザーコントロール内のコントロールに問題はありません。自体。私は(propdbテンプレートを使用して)依存関係プロパティで、キャンバスに基づいてカスタムコントロールを作っています:私のページで依存関係プロパティを持つユーザーコントロールのカスタムプロパティではデータバインドが機能しません(出力ウィンドウはクリーン)

public sealed partial class PresentationViewer : Canvas 
{ 

    #region Properties 

    public ISlide PresentationSlide 
    { 
     get 
     { 
      Debug.WriteLine("Get PresentationSlide"); 
      return (ISlide)GetValue(PresentationSlideProperty); 
     } 
     set 
     { 
      Debug.WriteLine("Set PresentationSlide"); 
      SetValue(PresentationSlideProperty, value); 
      this.ShowSlideContent(); 
     } 
    } 

    // Using a DependencyProperty as the backing store for PresentationSlide. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty PresentationSlideProperty = 
     DependencyProperty.Register(nameof(PresentationSlide), typeof(ISlide), typeof(PresentationViewer), new PropertyMetadata(null)); 

    #endregion 

    // Other codes... 
} 

、私がコントロールを使用し、そのプロパティをバインド:

<views:PresentationViewer x:Name="PresentationViewer" PresentationSlide="{Binding CurrentSlide, Mode=TwoWay}" /> 

これはどのようにあります私は、ページのDataContext設定:

public MainPage() 
    { 
     this.InitializeComponent(); 

     this.ViewModel = new MainPageViewModel(); 
     this.DataContext = this.ViewModel; 
    } 

をそして、これは私のMainPageViewModelのコードです:

public class MainPageViewModel : INotifyPropertyChanged 
{ 

    // Other codes... 

    public ISlide CurrentSlide 
    { 
     get 
     { 
      return this.CurrentPresentation?.Slides[this.CurrentSlideIndex]; 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void OpenSlide(int index) 
    { 
     if (index < 0) 
     { 
      index = 0; 
     } 

     if (index > this.TotalSlides - 1) 
     { 
      index = this.TotalSlides - 1; 
     } 

     this.currentSlideIndexField = index; 

     this.PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.CurrentSlideIndex))); 

     System.Diagnostics.Debug.WriteLine("Current Slide notified"); 
     this.PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.CurrentSlide))); 

     this.PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.PageCounter))); 
    } 

} 

CurrentSlideプロパティの変更の通知を印刷する行に注目してください。ただし、ユーザーコントロールのプロパティのセッターまたはゲッターは呼び出されません。

enter image description here

バインディングが双方向モードでは、すでに次のとおりです。ここでOpenSlideは(出力はプログラムの初めからである)と呼ばれて出力されます。私のページ(ラベルなど)内の他のコントロールも通知され、ページカウンタなどの内容が変更されたので、ViewModelの問題ではないと思います。カスタムコントロールクラスで何か不足していますか?バインディングはどのようにして作れますか?

答えて

1

XAML Loading and Dependency Propertiesで説明したように、依存プロパティのCLRラッパーが呼び出されない可能性があります。したがって、ブレークポイントにヒットせず、ShowSlideContentメソッドは実行されません。代わりに、フレームワークは依存関係プロパティのGetValueSetValueのメソッドを直接呼び出します。

プロパティ設定のためのXAMLプロセッサの動作 の現在のWPFの実装は完全にラッパーを迂回するので、あなたは は カスタム依存関係プロパティのラッパーのセット定義に任意の追加のロジックを置くべきではありません。そのようなロジックをセット の定義に入れると、プロパティでコードではなくXAMLに が設定されていると、ロジックは実行されません。変更されたプロパティ値に反応するために

、あなたはプロパティメタデータでPropertyChangedCallbackを登録する必要があります:

public ISlide PresentationSlide 
{ 
    get { return (ISlide)GetValue(PresentationSlideProperty); } 
    set { SetValue(PresentationSlideProperty, value); } 
} 

public static readonly DependencyProperty PresentationSlideProperty = 
    DependencyProperty.Register(
     nameof(PresentationSlide), 
     typeof(ISlide), 
     typeof(PresentationViewer), 
     new PropertyMetadata(null, PresentationSlidePropertyChanged)); 

private static void PresentationSlidePropertyChanged(
    DependencyObject o, DependencyPropertyChangedEventArgs e) 
{ 
    ((PresentationViewer)o).ShowSlideContent(); 
} 

あるいは、ラムダ式を持つ:

public static readonly DependencyProperty PresentationSlideProperty = 
    DependencyProperty.Register(
     nameof(PresentationSlide), 
     typeof(ISlide), 
     typeof(PresentationViewer), 
     new PropertyMetadata(null, 
      (o, e) => ((PresentationViewer)o).ShowSlideContent())); 
+0

ワンダフル!参照リンクをありがとうございました。私はUWPの記事から 'propdb'を使用していたので、私はこれについて全く知らなかった。 –

関連する問題