質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

88.31%

一つ目のコンボボックスの選択より、二つ目のコンボボックスのメニューを変更したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 970

bluerail

score 11

前提・実現したいこと

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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

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側にも変更が反映されるかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/13 14:36

    お陰様で、問題が解決しました。どうもありがとうございました。

    キャンセル

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

  • ただいまの回答率 88.31%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • UWPに関する質問
  • 一つ目のコンボボックスの選択より、二つ目のコンボボックスのメニューを変更したい