2011-08-15 14 views
0

私はContentControlのラッパーとして機能するUserControlを持っています。これは単にContentControlのタイトルです。ContentControlフィールドを持つカスタムUserControl

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"/> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 

<Grid Background="Green" Grid.Row="0"> 
    <TextBlock Text="{Binding Header}" Style="{StaticResource HeaderStyle}" Margin="12, 10, 0, 10" /> 
</Grid> 
    <ContentControl HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Content="{Binding Body}" Grid.Row="1"/> 
</Grid> 

そして、ここで私がコントロールを使用しようとするところだ。

<gbl:ListHeader Grid.Row="1" Visibility="{Binding HasMovies, Converter={StaticResource VisibilityConverter}}" Header="{Binding Path=LocalizedResources.movie_list_header, Source={StaticResource LocalizedStrings}}" > 
        <gbl:ListHeader.Body> 
         <ListBox SelectionChanged="ListBoxContainerSelectionChanged" ItemsSource="{Binding Movies}" ItemContainerStyle="{StaticResource HeaderListBoxItemStyle}"> 
          <ListBox.ItemTemplate> 
           <DataTemplate> 
            <gbl:MovieItemControl Header="{Binding MovieTitle}" Description="{Binding FormattedDescription}" Detail="{Binding FormattedDetail}" Opacity="{Binding IsSuppressed, Converter={StaticResource DimIfTrueConverter}}"/> 
           </DataTemplate> 
          </ListBox.ItemTemplate> 
         </ListBox> 
        </gbl:ListHeader.Body> 

データバインディングリストに問題が発生した、しかし、何もコントロールに表示しません。私はそれがまだそこにあると思うが、見るには小さすぎる(未定義のh/w)。

私が間違っていることはありますか?ヘッダーが正常に表示されるため、コントロールが多少動作しているように見えます。

編集:私はあなたが悪いことだユーザーコントロールの宣言であなたのDataContextにバインドするように見える私のコメントで言ったことに加えて

public partial class ListHeader : UserControl 
    { 
     private readonly ListHeaderData _data = new ListHeaderData(); 
     public ListHeader() 
     { 
      InitializeComponent(); 
      DataContext = _data; 
     } 

     public string Header 
     { 
      get { return (string)GetValue(HeaderProperty); } 
      set { SetValue(HeaderProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for Header. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty HeaderProperty = 
      DependencyProperty.Register("Header", typeof(string), typeof(ListHeader), new PropertyMetadata("",HeaderPropertyChanged)); 

     private static void HeaderPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var lh = d as ListHeader; 
      if (lh != null) 
       lh._data.Header = e.NewValue as string; 
     } 



     public object Body 
     { 
      get { return GetValue(BodyProperty); } 
      set { SetValue(BodyProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for Body. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty BodyProperty = 
      DependencyProperty.Register("Body", typeof(object), typeof(ListHeader), new PropertyMetadata(null, BodyPropertyChanged)); 

     private static void BodyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      var lh = d as ListHeader; 
      if (lh != null) 
       lh._data.Body = e.NewValue; 
     } 
    } 
    public class ListHeaderData : ViewModelBase 
    { 
     public ListHeaderData() 
     { 
      if (IsInDesignMode) 
      { 
       Header = "Custom Header Goes Here"; 
       Body = new Grid() { Background = new SolidColorBrush(Colors.Yellow) }; 
      } 
     } 
     private string _header; 
     public string Header 
     { 
      get { return _header; } 
      set { _header = value; RaisePropertyChanged("Header"); } 
     } 

     private object _body; 
     public object Body 
     { 
      get { return _body; } 
      set { _body = value; RaisePropertyChanged("Body");} 
     } 
    } 
+0

コードの後ろにもコードがある可能性があります。 –

+0

@HB更新された元の投稿。 –

+0

これらのプロパティが変更されたコールバックは何ですか?私はそれを見ているので、**プロパティが既にコールバックを変更しているプロパティである**コールバックを変更するプロパティではないので**プロパティに値を設定するだけでなく、目的を果たしません。 ViewModelでは、等価性があるかどうかをチェックし、等価性がない場合にのみプロパティーを変更します。 –

答えて

2

ここでは、コードビハインドLISTHEADERのためですそしてこのすべての問題。

UserControlのプロパティにバインドしたいが、ViewModelであるDataContextのプロパティに直接バインドすると思われるため、XAMLのインスタンスのBodyプロパティを設定すると、プロパティが内部結合。

のUserControlは、私はこのようなバインディングを行う知っているすべてのためにする必要があります

<UserControl Name="control" ...> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 

     <Grid Background="Green" Grid.Row="0"> 
      <TextBlock Text="{Binding Header, ElementName=control}" Style="{StaticResource HeaderStyle}" Margin="12, 10, 0, 10" /> 
     </Grid> 
     <ContentControl HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Content="{Binding Body, ElementName=control}" Grid.Row="1"/> 
    </Grid> 

はこれらの依存関係プロパティを取り除くコールバックを変更し、それが変更を確認するために、この形式にのviewmodelsでプロパティコードを変更します。

private int _MyProperty = 0; 
public int MyProperty 
{ 
    get { return _MyProperty; } 
    set 
    { 
     if (_MyProperty != value) 
     { 
      _MyProperty = value; 
      OnPropertyChanged("MyProperty"); 
     } 
    } 
} 
+0

お返事ありがとうございます。あなたのポストにはたくさんの情報がありますが、ユーザコントロールのDataContextを設定しないでください。ListHeaderのCodeBehindにはプロパティが必要ですか? –

+0

@willmel:多くの場合、継承されないDataContextにUserControlをバインドできるようにしたい場合、継承されないUserControlの中にUserControlを設定すると、それが継承されます。私はあなたのユースケースを知らないので、これはうまくいくかもしれませんが、多くの場合、DataContextをターゲットとするインスタンスのバインディングが、外部からは見えない内部的なセットをターゲットとするため、混乱を招く可能性があります。また、ビューモデルの作成にはビューが応答する必要があるのか​​、そうでないのかについての討論が必要なのかどうか、いくつかの論争があります。プロパティについてのあなたの質問とはどういう意味か分かりません... –

+0

申し訳ありませんが、私はあまり理解していません。あなたが説明したアイデアの使用例にリンクできますか?これは私がこれまでUserControlsをやってきた方法ですが、それが悪い設計であれば、私はそれを変更したいと思います。 –

関連する問題