概要
ComboBoxの選択を変更した際に、なんらかの理由でロールバック(選択前の状態に戻す)方法です。コードビハインドで処理するのが常套(?)なのかもしれませんが、MVVMを使用しており、処理が散逸するのを避けたかったという理由があります。
回避方法1は実現はできましたが、今一つ理解に苦しんでいます。
回避方法2を教えていただきました。
コード
<ComboBox HorizontalAlignment="Left"
Margin="10,38,0,0"
VerticalAlignment="Top"
Width="147"
ItemsSource="{Binding Path=ComboBoxList, Mode=OneWay}"
SelectedValue="{Binding Path=TextBoxValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
こんな ComboBoxがあったとする。
やりたいこと
private string textBoxValue;
public string TextBoxValue
{
get => textBoxValue;
set
{
if (value is string)
{
var _textBoxValue = TextBoxValue;
textBoxValue = value;
if (value == "test")
{
// 例えば "test" という文字は選択された場合、選択できなくする
textBoxValue = _textBoxValue;
}
RaisePropertyChanged(nameof(TextBoxValue));
}
}
}
TextBoxValue
の値は変わっているのだが、ComboBoxの値は変わらない(ロールバックしてくれない)。不思議。
回避方法1
private ObservableCollection<string> comboBoxList { get; set; }
public ObservableCollection<string> ComboBoxList
{
get => comboBoxList;
set
{
if (value == comboBoxList)
return;
comboBoxList = value;
RaisePropertyChanged(nameof(ComboBoxList));
}
}
private string textBoxValue;
public string TextBoxValue
{
get => textBoxValue;
set
{
if (value is string)
{
var _textBoxValue = TextBoxValue;
textBoxValue = value;
RaisePropertyChanged(nameof(TextBoxValue));
if (value == "test")
{
// 例えば "test" という文字は選択された場合、選択できなくする
// 元のデータをバックアップ
var _comboBoxList = ComboBoxList.ToList();
// リストを更新することで強制的にComboBoxの更新を行う
ComboBoxList.Clear();
_comboBoxList.ForEach(x => ComboBoxList.Add(x));
// 元のデータを戻す
textBoxValue = _textBoxValue;
RaisePropertyChanged(nameof(TextBoxValue));
}
}
}
}
ComboBoxの中身を全部消して、どこかに保持されているであろうComboBoxの選択値を消した上で、TextBoxValue
を再設定すると上手くいく。
回避方法2
@NCT48 さんにコメントで教えていただきました。
たぶん、こっちの方が簡単で実用的。
<ComboBox HorizontalAlignment="Left"
Margin="10,38,0,0"
VerticalAlignment="Top"
Width="147"
ItemsSource="{Binding Path=ComboBoxList, Mode=OneWay}"
SelectedValue="{Binding Path=TextBoxValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Delay=1}"
Delay
はミリ秒。
public string TextBoxValue
{
get => textBoxValue;
set
{
// 例えば "test" という文字が選択された場合、選択できなくする
if (value != "test")
{
textBoxValue = value;
}
// ComboBox以外にも通知する
RaisePropertyChanged(nameof(TextBoxValue));
}
}
ComboBox
だけしかないならRaisePropertyChanged
は不要です。