2016-07-09 4 views
1

に私はUserControlを次のようしている。ここでバインドユーザーコントロールのプロパティのItemsControl

public partial class ConstraintBlock : UserControl 
{ 
    public static readonly DependencyProperty LabelProperty = 
     DependencyProperty.Register("Constraint", typeof(Constraint) 
      , typeof(ConstraintBlock)); 

    public Constraint Constraint { get; set; } 

    public event EventHandler EditClicked; 

    public ConstraintBlock() 
    { 
     InitializeComponent(); 
    } 

    private void btnEdit_Click(object sender, RoutedEventArgs e) 
    { 
     MessageBox.Show(Constraint.ToString()); 
     if (this.EditClicked != null) this.EditClicked(this, e); 
    } 
} 

はそれのためのXAMLです:

<UserControl x:Class="MyApp.Controls.ConstraintBlock" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:MyApp.Controls" 
      mc:Ignorable="d" 
      d:DesignHeight="60" d:DesignWidth="500"> 
    <Grid Margin="5"> 
     <Grid> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="25" /> 
       <RowDefinition Height="25" /> 
      </Grid.RowDefinitions> 

      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="*" /> 
      </Grid.ColumnDefinitions> 

      <TextBlock x:Name="tbName" Grid.RowSpan="2" Text="{Binding Name}" /> 
      <Button x:Name="btnEdit" Grid.Row="1" Click="btnEdit_Click" /> 
     </Grid> 
    </Grid> 
</UserControl> 

制約として定義されたクラスで、次のとおりです。

namespace MyApp.Classes 
{ 
    public class Constraint 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
     public ConstraintObject Object { get; set; } 
     public ConstraintClause Clause { get; set; } 
     public Nullable<ConstraintOperator> Operator { get; set; } 
     public string Expression { get; set; } 
    } 

    [TypeConverter(typeof(EnumDescriptionTypeConverter))] 
    public enum ConstraintObject 
    { 
     Expression, 
     [Description("File Extension")] 
     FileExtension, 
     [Description("File Name")] 
     FileName 
    } 

    [TypeConverter(typeof(EnumDescriptionTypeConverter))] 
    public enum ConstraintClause 
    { 
     Contains, 
     [Description("Does Not Contain")] 
     DoesNotContain, 
     Date, 
     Length, 
     Like, 
     [Description("Not Like")] 
     NotLike, 
     Number 
    } 

    [TypeConverter(typeof(EnumDescriptionTypeConverter))] 
    public enum ConstraintOperator 
    { 
     [Description("=")] 
     EqualTo, 
     [Description(">")] 
     GreaterThan, 
     [Description("<")] 
     LessThan, 
     [Description(">=")] 
     GreaterThanOrEqualTo, 
     [Description("<=")] 
     LessThanOrEqualTo 
    } 
} 

次に、UIに次のItemsControlがあります。

<ItemsControl x:Name="constraintStack" ItemsSource="{StaticResource constraintCollection}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Grid> 
       <ctrls:ConstraintBlock Constraint="{Binding}" Grid.Row="2" 
             EditClicked="ConstraintBlock_EditClicked"/> 
      </Grid> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

IはconstraintCollectionリソースにConstraintを追加すると、ItemsControlConstraintBlockを示しており、また、私はちょうど追加Constraintの「名前」(プロパティ)として「名前」TextBlockで結合を示します。

問題は、私は、「編集」ボタンをクリックして、btnEdit_Click()が呼び出されたとき、私はMessageBoxライン上NullReferenceException得るということである - 何とかConstraintBlockオブジェクトのConstraintプロパティは、私が(しようと)しているにもかかわらず、nullのセットこれはItemsControlのXAMLにConstraint="{Binding}"となります。

このバインディングで何が問題になっていますか?

答えて

2

いいえMinimal, Complete, and Verifiable code exampleと言っても、確かに言うのは難しいです。あなたはConstraintタイプが何であるかを示しておらず、ConstraintBlock_EditClickedの実装を提供していません。

あなたのコードに表示される最も明白な問題は、Constraint依存プロパティを正しく実装していないことです。プロパティを登録しますが、ゲッターとセッターはそれぞれGetValue()SetValue()を呼び出すのではなく、デフォルトの実装を持っています。依存関係プロパティシステムに参加することなく、WPFはゲッターとセッターのプロパティではなく、DependencyPropertyの値を直接使用してプロパティを使用しようとすると、何も役に立ちません。

これはNullReferenceExceptionを得ることと一貫しており、Constraintが参照型であると仮定しています。 WPFに関する限り、依存関係プロパティの実際の値はnullのままであるため、例外が発生します。

私の理論が正しければ、あなたの財産の実装を変更しても問題解決します:

public Constraint Constraint 
{ 
    get { return (Constraint)GetValue(LabelProperty); } 
    set { SetValue(LabelProperty, value); } 
} 
+0

おかげで、ピーター - それは働きます!また、わかりやすくするために、Constraintクラスの定義を追加しました。 –