2011-11-14 7 views
2

のユニークなアイテムを確認するには、のリストを含むクラスmyClassがあります。このelementには、それらを識別する属性nameがあります。私のSilverlight 4アプリケーションでSilverlightデータバインドリスト

class element 
{ 
    string Name { get; set; } 
} 

class myClass 
{ 
    List<element> elements { get; } 
} 

要素のリストを表示するには、私は、Silverlightの-リストボックスにmyClass.elementsをデータバインド:

<ListBox> 
    <ListBox.ItemTemplate> 
    <DataTemplate> 
     <Grid> 
     <TextBox Text="{Binding Name, FallbackValue=[None], Mode=TwoWay, 
         NotifyOnValidationError=true, ValidatesOnExceptions=true}" /> 
... 

この方法で、elementNameへの変更は自動的に伝播されます。しかし:私はmyClassの特性に応じて、NamemyClass.elementsで一意であることを、確認する必要があり(およびいくつかのより多くの制約

当然のことながら、要素は、それが含まれています誰が知っていません(と、それは知っているべきではありません、だから私の問題は:どのように(名前プロパティの設定者の)要素の制約をチェックすることができますか?私は本当にエラー通知を実装しているので、Silverlight-Databindingを本当に使いたいと思います。

私は elementがIMPL必要があることをお勧めしたい事前に

おかげで、
フランク

+0

1つの質問ですが、ユーザーが複製を入力しようとするとアプリは何をすると思いますか?エレメントセッターがアイテムを検証するためにコンテナークラスがサブスクライブしているイベントを発生させることができます。 – EtherDragon

+0

アプリケーションは値を保存してはならず、テキストボックスは(NotifyOnValidationErrorとValidatesOnExceptionsを介して)エラーを表示するので、設定者はエラーを発生させる必要があります。私がセッターでイベントを起こしたとき、私はセッターで検証結果に反応することができませんでした(プロパティを設定せず、エラーを発生させません)。 – Aaginor

答えて

1

INotifyProperyChangeとmyClassは、変更をリッスンしてから、重複をチェックして例外をスローするか、IDataErrorInfo、INotifyDataErrorInfoまたはカスタムインジケータを使用してエラーを示す必要があります。 (オブザーバーパターンを実装するので、ここではmyClassはそのアイテムのオブザーバーです)。

カスタム方法では、重複した項目に「IsDuplicate」プロパティを設定し、背景(赤色)の色にバインドすることができます。ここで重複した名前を意図的に設定したい場合は、以前に入力した項目を修正したい場合は、ユーザーにとってより便利です。また、リスト内のすべてを指定すると、重複を見つけるのが簡単になります。

UPDATE:ここ

は誤差の指標です。ちょうど変更された項目は、それのために重複 - 赤いフォントを持っています。ここで

<Style TargetType="{x:Type TextBox}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Path=IsDuplicate}" Value="True"> 
      <Setter Property="Foreground" Value="Red" /> 
     </DataTrigger> 
     <Trigger Property="Validation.HasError" Value="true"> 
      <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, 
       Path=(Validation.Errors)[0].ErrorContent}"/> 
      <Setter Property="BorderBrush" Value="Red"/> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

ValidatesOnDataErrorsに注意し、項目テンプレートです:

class Element : INotifyPropertyChanged, IDataErrorInfo 
{ 
    private string _name; 
    public string Name 
    { 
     get { return _name; } 
     set { _name = value; 
     if(PropertyChanged != null) 
      PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Name")); 
     } 
    } 

    private bool _isDuplicate; 
    public bool IsDuplicate 
    { 
     get { return _isDuplicate; } 
     set 
     { 
      _isDuplicate = value; 
      PropertyChanged.Invoke(this, new PropertyChangedEventArgs("IsDuplicate")); 
     } 
    } 
    //IDataErrorInfo 
    public event PropertyChangedEventHandler PropertyChanged; 

    public string this[string columnName] 
    { 
     get 
     { 
      if (IsDuplicate) 
       return "Duplicate col" + columnName; 
      return null; 
     } 
    } 

    public string Error 
    { 
     get { return null; } 
    } 
} 

そして最後に、myClassはのPropertyChangedに耳を傾け、重複チェックを呼び出す必要があります。ここでは

<ListBox.ItemTemplate> 
     <DataTemplate> 
      <Grid> 
       <TextBox Text="{Binding Path=Name, Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True}" /> 
      </Grid> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 

は、あなたの要素のクラスがあります。

+0

こんにちはミカライ、答えをありがとう、これは良い方法のように聞こえる!私がまだ分かっていないのは、myClassが(複製中の)エラーを示しているとき、要素の(IDataErrorInfo)例外を発生させてテキストボックスに表示させるにはどうすればいいですか?現在、要素セッターに例外をスローしますが、myClassが重複をチェックしているとき、私はもはや要素のセッターにいません。 – Aaginor

+0

私はテキストに答えるコードを投稿しました - 助けてくれることを期待してください:) – mikalai

+0

ああ、非常に良い例、多くの感謝! IDataErrorInfoの実装は非常に便利で、他の部分でも便利です:) – Aaginor

関連する問題