一つ目のコンボボックスの選択より、二つ目のコンボボックスのメニューを変更したい
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 970
前提・実現したいこと
UWPのアプリつについて質問させていただきます。言語はC#を使用しており、MWWM方式で、prism.windowsを使用しております。
実現したいことは、二つのコンボボックスがあり、一つ目のコンボボックス(グループ)の選択により、二つ目のコンボボックス(明細)のメニューを変更したい。
発生している問題・エラーメッセージ
コンボボックス(グループ)にてAを選択すると、コンボボックス(明細)のメニューはA1が一つだけ表示される。次に、コンボボックス(グループ)にてBを選択すると、コンボボックス(明細)のメニューはA1のまま。本来は、B1、B2を表示したい。
該当のソースコード
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prism.Mvvm; // add
namespace TestComboBox2.ViewModels
{
public class MainPageViewModel:BindableBase
{
public Views.MainPage View { get; private set; } = null;
public void Initialize(Views.MainPage mainPage)
{
View = mainPage;
}
public MainPageViewModel()
{
// グループの追加
ChangeGroupId();
}
private List<CbGroup> CbGroupList = new List<CbGroup>();
public List<CbGroup> CbGroupLists
{
get { return CbGroupList; }
set { this.SetProperty(ref this.CbGroupList, value); }
}
private List<CbItem> CbItemList = new List<CbItem>();
public List<CbItem> CbItemLists
{
get { return CbItemList; }
set { this.SetProperty(ref this.CbItemList, value); }
}
private string txGroupId;
public string TxGroupId
{
get { return txGroupId; }
set
{
this.SetProperty(ref this.txGroupId, value);
// アイテムの追加
ChangeItemId(txGroupId);
}
}
private string txItemId;
public string TxItemId
{
get { return txItemId; }
set { this.SetProperty(ref this.txItemId, value); }
}
private void ChangeGroupId()
{
CbGroupList.Add(new CbGroup("A", "A"));
CbGroupList.Add(new CbGroup("B", "B"));
CbGroupList.Add(new CbGroup("C", "C"));
}
private void ChangeItemId(string ValueId)
{
try
{
// 全件 削除する
if (CbItemLists != null)
{
CbItemList.Clear();
}
TxItemId = null;
//
switch (ValueId)
{
case "A":
CbItemList.Add(new CbItem("A1", "A1"));
//CbItemList.Add(new CbItem("A2", "A2"));
//CbItemList.Add(new CbItem("A3", "A3"));
break;
case "B":
CbItemList.Add(new CbItem("B1", "B1"));
CbItemList.Add(new CbItem("B2", "B2"));
//CbItemList.Add(new CbItem("B3", "B3"));
break;
case "C":
CbItemList.Add(new CbItem("C1", "C1"));
CbItemList.Add(new CbItem("C2", "C2"));
CbItemList.Add(new CbItem("C3", "C3"));
break;
}
}catch(Exception ex)
{
string stErrMessage = ex.Message;
}
}
}
public class CbGroup
{
public string GroupId { get; set; }
public string GroupName { get; set; }
public CbGroup(string ValueId, string ValueName)
{
GroupId = ValueId;
GroupName = ValueName;
}
}
public class CbItem
{
public string ItemId { get; set; }
public string ItemName { get; set; }
public CbItem(string ValueId, string ValueName)
{
ItemId = ValueId;
ItemName = ValueName;
}
}
}
<Page
x:Class="TestComboBox2.Views.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestComboBox2"
xmlns:views="using:TestComboBox2.Views"
xmlns:viewmodels="using:TestComboBox2.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Style.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
<Grid>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource TextBlckFontSize}"
Text="グループ"
Foreground="Black"
/>
<ComboBox Style="{StaticResource ComboBoxStype}"
ItemsSource="{Binding CbGroupLists,Mode=OneWay}"
SelectedValue="{Binding TxGroupId,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="GroupId"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding GroupName,Mode=OneWay}"/>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Style="{StaticResource TextBlckFontSize}"
Foreground="Black"
Text="明細"
/>
<ComboBox Style="{StaticResource ComboBoxStype}"
ItemsSource="{Binding CbItemLists,Mode=OneWay}"
SelectedValue="{Binding TxItemId,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="ItemId"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding ItemName,Mode=OneWay}"/>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</StackPanel>
</Grid>
</Page>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
namespace TestComboBox2.Views
{
public sealed partial class MainPage : Page
{
public ViewModels.MainPageViewModel ViewModel { get; private set; } = new ViewModels.MainPageViewModel();
public MainPage()
{
this.InitializeComponent();
ViewModel.Initialize(this);
this.DataContext = ViewModel;
}
}
}
試したこと
コンボボックス(明細)はCbItemListにバインディングしています。CbItemList自体を調べると、B1・B2が代入されています。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
CbItemListsの内容更新がVM側からView側に通知できていないことが原因と思われます。
案1 RaisePropertyChanged(nameof(CbItemLists));
をCbItemListの内容変更後(ChangeItemIdメソッドのswitchの後ろ)に追加する
List はCbItemLists.Clear()
やCbItemLists.Add(item)
を呼び出しても中身の変更は通知されません。BindableBaseクラスを元にしたSetPropertyによる更新通知は実装されているようですが、CbItemListsに対する代入を行っていないためSetPropertyが呼ばれず、変更通知はされません。
つまりリストが更新されたことを手動で通知する必要があります。そのためRaisePropertyChanged
を利用して強制的に通知します。
案2 CbItemListをObservableCollection<CbItem>で定義しなおす
ObservableCollectionはINotifyCollectionChangedを実装したコレクションでComboBox.SourceItemsにセットした場合、リスト内容の変更がリアルタイムに反映されます。
ObservableCollectionを利用する場合はRaisePropertyChanngedを使用する必要はありませんし、SetProperty等のセッターゲッター実装も不要になります。
public ObservableCollection<CbItem> CbItemLists { get; } = new ObservableCollection<CbItems>();
あとはClearやAddするだけでComboBox側にも変更が反映されるかと思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.31%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2019/05/13 14:36