2016-07-09 2 views
1

을 ItemsControl에하기 : 제약 조건과 같이 정의 된 클래스는 다음입니다바인딩 사용자 정의 컨트롤 속성

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

: 여기

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입니다

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> 

은 내가이 ConstraintconstraintCollection 자원의 ItemsControlConstraintBlock를 보여줍니다 추가하고, 또한 내가 추가 한 Constraint의 "이름" "이름"(속성)과 TextBlock 바인딩을 표시합니다.

문제는 내가 "편집"버튼을 클릭하고 btnEdit_Click()가 호출 될 때, 나는 MessageBox 줄에 NullReferenceException 얻을 수 있다는 것입니다 - 어떻게 든 ConstraintBlock 개체의 Constraint 속성이 나는 (시도)에도 불구하고, null의 세트 이 ItemsControl에 대한 XAML의 Constraint="{Binding}"입니다.

이 바인딩에 어떤 문제가 있습니까? 좋은 Minimal, Complete, and Verifiable code example없이

답변

2

그것은 확실히 말할 어렵다. Constraint 유형을 표시하지 않았으며 ConstraintBlock_EditClicked에 대한 구현을 제공하지 않았습니다.

즉, 코드에서 볼 수있는 가장 명백한 문제는 올바르게 Constraint 종속성 속성을 구현하지 않았다는 것입니다. 속성을 등록하지만 getter 및 setter는 각각 GetValue()SetValue()을 호출하는 대신 기본 구현을 갖습니다. 종속성 속성 시스템에 참여하지 않고 WPF는 getter 및 setter 속성 대신 DependencyProperty 값을 통해 속성을 직접 사용하려고 시도 할 때 아무런 도움이되지 않습니다.

이것은 NullReferenceException과 일치하며 Constraint은 참조 유형이라고 가정합니다. WPF에 관한 한 종속성 속성의 실제 값은 null이므로 예외가 발생합니다.

내 이론이 맞다면, 당신의 재산 구현을 변경하면 문제가 해결됩니다 :

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

감사합니다, 피터 - 그것은 작동합니다! 또한 명확성을 위해 Constraint 클래스의 정의를 추가했습니다. –

관련 문제