🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

4290閲覧

WPF ComboBoxのReactiveCollectionで定義したItemSourceの内容を入れ替えた際にSelectedValueを復元したい

miyag

総合スコア1

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

0クリップ

投稿2021/03/18 14:51

前提・実現したいこと

WPFで一定時間ごとにComboBoxの中身を更新し
その際に、ComboBoxの選択状態を元に戻そうとしています。
ComboBoxの中身は更新されますが、選択状態が元に戻っていない状態です。
※未選択状態になっているようです

ComboBoxの項目を選択した際に処理を行いたいので、
ReactivePropertyを使っています。

どのようにすればよいでしょうか?

該当のソースコード

MainWindow.xaml

xaml

1<Window x:Class="WpfApp4.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:WpfApp4" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <!--データコンテキスト定義--> 10 <Window.DataContext> 11 <local:MainWindowViewModel /> 12 </Window.DataContext> 13 <Grid> 14 <Grid.RowDefinitions> 15 <RowDefinition Height="auto"/> 16 <RowDefinition /> 17 </Grid.RowDefinitions> 18 <ComboBox ItemsSource="{Binding ListData}" SelectedValue="{Binding SelectedNo.Value, Mode=TwoWay}" Margin="10,0,10,0"></ComboBox> 19 </Grid> 20</Window>

MainWindowViewModel.cs

cs

1using Reactive.Bindings; 2using Reactive.Bindings.Extensions; 3using System; 4using System.ComponentModel; 5using System.Reactive.Disposables; 6using System.Reactive.Linq; 7using System.Security.Cryptography; 8using System.Text; 9 10namespace WpfApp4 11{ 12 public class MainWindowViewModel 13 : INotifyPropertyChanged 14 { 15 public event PropertyChangedEventHandler PropertyChanged; 16 private CompositeDisposable Disposable { get; } = new CompositeDisposable(); 17 18 public ReactiveCollection<string> ListData { get; private set; } 19 20 public ReactiveProperty<string> SelectedNo { get; set; } 21 22 23 public MainWindowViewModel() 24 { 25 this.ListData = new ReactiveCollection<string>(); 26 this.SelectedNo = new ReactiveProperty<string>(); 27 // コンボ選択時の処理 28 this.SelectedNo.Subscribe(_ => 29 { 30 // 何か処理 31 }); 32 33 // 一定時間ごとに処理を実行 34 Observable.Timer(TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(10000)) 35 .Subscribe(x => 36 { 37 var selectedNo = this.SelectedNo.Value; 38 // リスト更新 39 this.ListDataUpdate(); 40 // リストの選択状態を戻す 41 this.SelectedNo.Value = selectedNo; 42 }).AddTo(this.Disposable); 43 } 44 45 private void ListDataUpdate() 46 { 47 var @byte = new byte[sizeof(int)]; 48 using (var crypto = new RNGCryptoServiceProvider()) 49 crypto.GetBytes(@byte); 50 var seed = BitConverter.ToInt32(@byte, 0); 51 var random = new Random(seed); 52 int max = random.Next(50); 53 54 // リスト更新 55 this.ListData.ClearOnScheduler(); 56 for (int i = 1; i <= max; i++) 57 { 58 this.ListData.AddOnScheduler(i.ToString()); 59 } 60 } 61 } 62} 63

補足情報(FW/ツールのバージョンなど)

.NET Core 3.1
ReactiveProperty 7.8.1

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

RXはあまりわかっていませんが、更新前に選択してるような状態なんじゃないでしょうか?

miyagさんの意図通りかちょっと自信がありませんが、このようにしたところ選択は維持されました。

cs

1using Reactive.Bindings; 2using Reactive.Bindings.Extensions; 3using System; 4using System.ComponentModel; 5using System.Diagnostics; 6using System.Reactive.Disposables; 7using System.Reactive.Linq; 8using System.Threading; 9 10namespace Questions328623 11{ 12 public class MainWindowViewModel : INotifyPropertyChanged 13 { 14 public event PropertyChangedEventHandler PropertyChanged; 15 private CompositeDisposable Disposable { get; } = new CompositeDisposable(); 16 17 public ReactiveCollection<string> ListData { get; } = new ReactiveCollection<string>(); 18 19 public ReactiveProperty<string> SelectedNo { get; } = new ReactiveProperty<string>(); 20 21 22 public MainWindowViewModel() 23 { 24 //SelectedNo.Subscribe(_ => { }); 25 26 Observable.Timer(TimeSpan.FromSeconds(0.5), TimeSpan.FromSeconds(10)) 27 .ObserveOn(SynchronizationContext.Current) 28 .Subscribe(_ => 29 { 30 var selectedNo = SelectedNo.Value; 31 ListDataUpdate(); 32 SelectedNo.Value = selectedNo; 33 34 Debug.WriteLine(SelectedNo); 35 }).AddTo(Disposable); 36 } 37 38 private Random random = new Random(); 39 private void ListDataUpdate() 40 { 41 ListData.Clear(); 42 var max = random.Next(50); 43 for (var i = 1; i <= max; i++) 44 { 45 ListData.Add(i.ToString()); 46 } 47 } 48 } 49}

投稿2021/03/18 16:07

編集2023/07/26 15:14
TN8001

総合スコア9855

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyag

2021/03/22 13:33

返信が遅れて申し訳ないです。 頂いたコードで選択が維持できました。ありがとうございます。 書かれている通り、リスト更新の部分が終わる前に値を設定してしまっていたようです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問