2011-09-12 15 views
3

オブジェクトの名前をnullにすることができるクラスがあります。 SilverlightのリストボックスでSilverlightで最初の値がnullの場合の2番目のプロパティへのバインド

public class Thing 
{ 
    /// <summary> 
    /// The identifier of the thing 
    /// </summary> 
    /// <remarks> 
    /// This will never be null. 
    /// </remarks> 
    public string Identifier { get; set; } 
    /// <summary> 
    /// The name of the thing 
    /// </summary> 
    /// <remarks> 
    /// This MAY be null. When it isn't, it is more descriptive than Identifier. 
    /// </remarks> 
    public string Name { get; set; } 
} 

、私は私がのTextBlockにバインドされた名前持ってDataTemplateを使用します。名前がnullの場合しかし、これは明らかに非常に良い見ていない

<DataTemplate x:Key="ThingTemplate"> 
    <Grid> 
     <TextBlock TextWrapping="Wrap" Text="{Binding Name}" /> 
    </Grid> 
</DataTemplate> 

を。理想的には、

string textBlockContent = thing.Name != null ? thing.Name : thing.Identifier; 

と同等のものを使用したいと思いますが、モデルオブジェクトを変更することはできません。これを行う良い方法はありますか?

私はConverterを使うことを考えましたが、Nameプロパティではなく、オブジェクト自体にコンバータをバインドする必要があります。これは問題ありませんが、NameまたはIdentifierのいずれかが変更されたら、どのように再バインドしますか? IValueConverterは、オブジェクトのINotifyPropertyChangedイベントを手動でリッスンすると、再変換を強制する方法がないようです。

これを行う最善の方法に関するお考えですか?

+0

InstanceNameのいずれかを返すコンバータを使用[Equiv。 (XAMLバインディングのCoalesce()へ)?](http://stackoverflow.com/questions/6947728/equiv-to-coalesce-in-xaml-binding) –

+0

具体的にしてください。それはSilverlight、またはWPFですか? – Nawaz

+0

私が知る限り、コードを変更することなくこれを行うことはできません。厳密にXAMLを使用する方法が見つかった場合は、おそらくハックと見なされます。 – qJake

答えて

0

があるものの残念ながら、Silverlightは、これを直接サポートしていない、それが結合Textプロパティにバインドします。 したがって、値をTextに割り当てるたびに呼び出されます。内部の後にあなたにまでConverterを選択してください。Textのようになります。

可能な解決策の1つは、モデルのNameおよびIdentifierプロパティに基づいてConverterから割り当て可能な文字列特殊プロパティをNameAndIdentifierにすることです。

0

ViewModel/Presenter(または呼び出したいもの)にカスタム表示プロパティを作成する必要があります。基本的に、あなたは上記の投稿のコードを変更する必要があり、これはそれに追加:

public readonly string DisplayName 
{ 
    get 
    { 
     return Name ?? Identifier; 
    } 
}

他の方法は、私の知る限り、ハックになるだろう。

+0

'?'演算子を使うべきです: 'return Name ??識別子; '。これはOPが彼がモデルを変えることができないと言いましたので、それは疑問ですが、一般的には最高の解決策です。 – dlev

+1

他の誰かがこのモデルを編集できる*この質問を見ることができるかどうかは言及する価値があります。 '?'演算子についての良い点は、私はいつもそれを忘れています。 ;) – qJake

3

それはあなたのThingインスタンスに直接結合するようにあなたは、バインディングを変更することができます。

<DataTemplate x:Key="ThingTemplate"> 
    <Grid> 
     <TextBlock TextWrapping="Wrap" Text="{Binding .,Converter={StaticResource ConvertMyThingy}" /> 
    </Grid> 
</DataTemplate> 

ことが可能重複渡さThingインスタンスから

public class ConvertMyThingyConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var thing= value as Thing; 
     if(thing == null) 
      return String.Empty; 
     return thing.Name ?? thing.Identifier; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

名前が更新されると、テキストをどのように変更できますか? – Bryan

+0

あなたのモデルやビューで更新されたことを意味しますか? – thumbmunkeys

+0

これは、これを処理するための良い、簡単な方法ですが、他のタイプには再利用できません。タイプ(またはインターフェイス)ごとにカスタムコンバータが必要です。 –

関連する問題