3

次のシナリオ:

<ComboBox ItemsSource="{Binding Path=Names}"
          SelectedItem="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}">
</ComboBox>

Namesは、ViewModelのコードによって変更される可能性のある文字列コレクションです。たとえば、名前は男性の名前(John、Paul、George)または女性の名前(Mary、Jane、Karen)のいずれかに設定できます。

男性のコレクションがアクティブで、ユーザーが「John」を選択してSelectedItemにしたとします。これで、コレクションが女性の名前に変わります。デフォルトでは、SelectedItemはNullに設定され、Johnは表示されなくなります。代わりに、空の文字列が表示されます。

私が達成したいのは、「John」はコレクションに含まれていなくても、SelectedItemとして表示されていることです。ただし、コレクションの一部ではないため、SelectedItemの色を赤に変更したいと思います。

IsEditableプロパティをいじってみましたが、ComboBoxの外観の変化が気に入らなかった。とにかく、ユーザーは手動でテキストを入力できないようにする必要があります。

さまざまなテンプレートとスタイル(たとえば、Template、ItemTemplate、ItemContainerStyle)を使用しようとしましたが、自分の好みに合わせて使用​​する方法が見つかりませんでした。

提供されたComboBoxを必要な方法でスタイル設定することは可能ですか、それとも独自のユーザーコントロールを作成する必要がありますか?

編集:私は私が一緒に暮らすことができる解決策を見つけました。

<ComboBox IsEditable="True" IsReadOnly="True"
          ItemsSource="{Binding Path=Names}"
          Text="{Binding Path=Name}">
  <ComboBox.Style>
    <Style TargetType="{x:Type ComboBox}">
      <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsNameInCollection}" Value="False">
          <Setter Property="Foreground" Value="Red"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ComboBox.Style>
  <ComboBox.ItemContainerStyle>
    <Style TargetType="{x:Type ComboBoxItem}">
      <Setter Property="Foreground" Value="Black"/>
    </Style>
  </ComboBox.ItemContainerStyle>
</ComboBox>

ViewModelでは、 Namesコレクションが変更されたときにNameプロパティが変更されないことを確認します。ブールプロパティIsNameInCollectionは、 Nameプロパティまたはコレクションが変更されたときに更新されます。

4

1 に答える 1

1

注:これは実際の実用的な答え/解決策ではありませんが、検討する価値があると思われるいくつかの考えがあります。

まず、SelectedItemコレクションが変更された場合(新しいコレクションに置き換えるか、クリアして補充することにより)、は常にnullに変更されます。したがってName、あるオブジェクトのプロパティにバインドしているときに、そのプロパティが内部でnullでオーバーライドされるのを防ぐことができますか?そうすれば、ComboBoxで値が変更されない可能性があります(値を固定するためにTwoWayBindingも必要になる場合がありNameます。または、変更イベントを発生させることもできますが、テストによって異なります)。

次に、レンダリングを変更する必要があるため、最も簡単な方法は、ItemTemplateとカスタムIValueConverter実装を使用して、特別なエントリの情報を異なる色/スタイルに変換することです。ただし、これの欠点は、ItemTemplate通常、選択されている現在のエントリを含むすべてのエントリにが使用されることです。

これに対処する1つの方法は、ItemTemplateSelectorここで説明されているようなものを使用することです:http ://www.wpftutorial.net/datatemplates.html (セクション「DataTemplateSelectorを使用してデータに応じてテンプレートを切り替える方法」)

別の方法は、プレーンな文字列の代わりにコンテナを使用することです。そのコンテナは、別のレンダリングを示すためのブール値も保持します。そのブール値はで使用できますItemTemplate。ただし、このシナリオでは、すべての文字列値をラップする必要があります。

第3に、選択した値が現在のリストにない古い値のままで、ユーザーが別の値を選択した場合、ComboBoxはどのように反応する必要がありますか。1つの論理は、古い値が消えるだけで、ユーザーがそれを選択し直すことができないというものです。それがまだリストで利用可能である必要がある場合は、何らかの方法で現在の値のリストに追加する必要がありますが、それが特別な値であることをマークします。どちらの場合も、現在使用可能なリストに従って無効な値が選択されたかどうかを後で検出するロジックも必要です。

これが実用的な解決策を見つけるのに役立つことを願っています。

于 2012-04-22T15:20:38.290 に答える