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

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

ただいまの
回答率

90.46%

  • C#

    9290questions

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

コンボボックスへのアイテム設定について

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,137

GOYOSHI

score 9

お世話になります。

WPF、C#での開発を勉強中のものです。データベースにPostgreSQLを使用してのアプリを進めていまして2つのコンボボックスのうち1つの目のコンボボックスの選択された値をもとに2つ目のコンボボックスの値リストを作成するものですがうまくいきません。

1つ目のコンボボックスの値が選択されたということを知るためにBlendのSelectionChangedを使用しました。以下にコードを示します。XAMLです。

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:AIT_Shipment2.Views"
             xmlns:vm="clr-namespace:AIT_Shipment2.ViewModels"
             xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
             xmlns:System="clr-namespace:System;assembly=mscorlib"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
             x:Class="AIT_Shipment2.Views.ShukkaJyokyo"
             mc:Ignorable="d" 
             d:DesignHeight="640" d:DesignWidth="1050">
    <UserControl.Resources>
        <vm:ShukkaJyokyoVM x:Key="ViewDataDataSource" d:IsDataSource="True"/>
    </UserControl.Resources>
    <UserControl.DataContext>
        <vm:ShukkaJyokyoVM />
    </UserControl.DataContext>
    <Grid Background="White">
        <StackPanel HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top">
            <StackPanel Height="24" Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,10">
                <Label x:Name="label" Content="納入日:" Margin="20,0,0,0"/>
                <xctk:DateTimePicker x:Name="dtpSdate" Width="110" ShowButtonSpinner="False" 
                                     TimePickerVisibility="Hidden" Format="LongDate" 
                                     Value="{Binding Path=StartDate}" AutoCloseCalendar="True" AllowTextInput="False"/>
                <Label x:Name="label1" Content="~"/>
                <xctk:DateTimePicker x:Name="dtpEdate" Width="110" ShowButtonSpinner="False" 
                                     TimePickerVisibility="Hidden" Format="LongDate" 
                                     Value="{Binding Path=EndDate}" AllowTextInput="False" AutoCloseCalendar="True"/>
                <Label x:Name="label2" Content="納入先:" Margin="20,0,0,0"/>
                <ComboBox x:Name="cmbNsaki" Width="220" 
                          ItemsSource="{Binding trhksks}" 
                          SelectedValuePath="tkCD"
                          SelectedItem="{Binding SelectedtkCD}">
                    <ComboBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding tkCD}" Margin="2.5"/>
                                <TextBlock Text="{Binding tkNM}" Margin="2.5"/>
                            </StackPanel>
                        </DataTemplate>
                    </ComboBox.ItemTemplate>
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="SelectionChanged">
                            <ei:CallMethodAction TargetObject="{Binding}" MethodName="Execute"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </ComboBox>
                <Label x:Name="label3" Content="便:" Margin="20,0,0,0"/>
                <ComboBox x:Name="cmbBin" Width="50"
                          ItemsSource="{Binding binLists}"
                          DisplayMemberPath="BinNo"
                          SelectedValuePath="BinNo">
                </ComboBox>
                <Button x:Name="button" Content="表示" Margin="50,0,0,0" Width="100" Height="24"/>
            </StackPanel>
            <StackPanel Height="410">
                <DataGrid x:Name="dataGrid" Height="400"/>
            </StackPanel>
            <StackPanel Height="40" Orientation="Horizontal" HorizontalAlignment="Right">
                <!--<TextBox x:Name="textBox" Height="23" TextWrapping="Wrap" Text="{Binding SelectedValue, ElementName=cmbNsaki}" Width="120"/>-->
                <Button x:Name="button1" Content="Button" Width="100" Margin="0"/>
                <Button x:Name="button2" Content="Button" Width="100" Margin="100,0,0,0"/>
                <Button x:Name="button3" Content="Button" Width="100" Margin="30,0,20,0"/>
            </StackPanel>
        </StackPanel>
    </Grid>
</UserControl>

``` 次にViewMODELに該当するコードです。

using System.Collections.Generic;  
using System.Collections.ObjectModel;  
using System.ComponentModel;  
using System.Linq;  
using System.Runtime.InteropServices.ComTypes;  
using System.Text;  
using System.Threading.Tasks;  
using System.Windows.Data;  

namespace AIT_Shipment2.ViewModels  
{  
public class ShukkaJyokyoVM : ViewModelBase  
{  
private DateTime _StartDate = DateTime.Now;  
public DateTime StartDate  
{  
get { return _StartDate; }  
set  
{  
if (_StartDate != value)  
{  
_StartDate = value; OnPropertyChanged("StartDate");  
}  
}  
}  

private DateTime _EndDate = DateTime.Now;  
public DateTime EndDate  
{  
get { return _EndDate; }  
set  
{  
if (_EndDate != value)  
{  
_EndDate = value; OnPropertyChanged("EndDate");  
}  
}  
}  

// 得意先マスタよりコードと名称をコレクションに設定  
//IList<Trhksk> trhksks = new ObservableCollection<Trhksk>();  
public IList<Trhksk> trhksks  
{  
get  
{  
using (var db = new Models.PgSQLConnection(clsConst.dBID, clsConst.dBPW, clsConst.dBSC))  
{  
var b = from t in db.bomm_torihikisakis  
where t.enable == 0  
select new Trhksk  
{  
tkCD = t.torihikicd,  
tkNM = t.torihikinm  
};  
return b.ToList();  
}  
}  
}  
// 取引先の選択を受け取る  
public Trhksk SelectedtkCD { get; set; }  

//便リスト作成  
//public IList<binList> binLists { get; set; }  
public ObservableCollection<binList> binLists { get; set; }  


public void Execute()  
{  
if (SelectedtkCD == null)  
{  
return;  
}  
using (var db = new Models.PgSQLConnection(clsConst.dBID, clsConst.dBPW, clsConst.dBSC))  
{  
var b = from t in db.koum_shukkabins  
where t.nonyusaki == SelectedtkCD.tkCD  
orderby t.bin  
select new binList  
{  
BinNo = t.bin.ToString()  
};  
//binLists = b.ToList();  
ObservableCollection<binList> binLists = new ObservableCollection<binList>(b.ToList());  
}  
}  
//// 便リスト作成  
//public IList<binList> binLists  
//{  
//    get  
//    {  
//        using (var db = new Models.PgSQLConnection(clsConst.dBID, clsConst.dBPW, clsConst.dBSC))  
//        {  
//            var b = from t in db.koum_shukkabins  
//                    where t.nonyusaki == "3230-1"  
//                    orderby t.bin  
//                    select new binList  
//                    {  
//                        BinNo = t.bin.ToString()  
//                    };  
//            return b.ToList();  
//        }  
//    }  
//}  
}  

// 出荷状況画面得意先選択設定  
public class Trhksk  
{  
public string tkCD { get; set; }  
public string tkNM { get; set; }  
}  

public class binList  
{  
public string BinNo { get; set; }  
}  

コード  


以下のコードで最初からバインディングするのであればリストが作成されることは確認いたしました。
// 便リスト作成
public IList<binList> binLists
{
get
{
using (var db = new Models.PgSQLConnection(clsConst.dBID, clsConst.dBPW, clsConst.dBSC))
{
var b = from t in db.koum_shukkabins
where t.nonyusaki == "3230-1"
orderby t.bin
select new binList
{
BinNo = t.bin.ToString()
};
return b.ToList();
}
}
}

デバッグでは『Execute()』は実行され、『where t.nonyusaki == SelectedtkCD.tkCD』にも選択された値が設定されることは確認できました。

プロパティーの受け渡しなど理解度不足とは思いますがなどアドバイスいただけましたら助かります。

また、作法等で『動くけどこれはちょっとおかしい。』などもありましたらご指摘お願いできればと思います。

以上、よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+1

私も複数の ComboBox を置いて、それぞれの選択内容によって選択肢を変更することをよくやります。
その場合は、ComboBox の DropDownOpened イベントで自身の ItemsSource を変更しています。
そうすることで、自由度の高いUIを少ない手間で実装できます。
欠点としては、DBに都度接続すると時間がかかるので事前にキャッシュを持つ必要が出てくることが考えられます。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/15 08:34

    ご回答ありがとうございました。
    DropDownOpened イベントというものもあるんですね。機会がありましたら取り組んでみたいと思います。
    また、DBのキャッシュにも興味をひかれました。今製作中のものもDBを読み込むためのタイムラグ的なものが大きく、どうにかしなければと思っていたところでした。
    質問させていただくことがあろうかと思いますがよろしくお願いいたします。

    キャンセル

checkベストアンサー

0

//binLists = b.ToList();  
ObservableCollection<binList> binLists = new ObservableCollection<binList>(b.ToList());  

ここが悪い。せっかくbinListsに紐付いているのに、newしたら、ひも付きを切れてしまっている。
この場合、binListsをクリヤーしてから、追加していくという処理が必要。

それは面倒なので、ObservableCollectionを使うより、普通のListを使って、TwoWayにすべき。
あとは、binListsが切り替えたことをOnPropertyChanged("binLists");で通知しよう。 

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/15 08:29

    ご回答ありがとうございます。

    ご指摘の通りコレクションではなくリストを利用させていただき
    public IList<binList> binLists { get; set; }

    binLists = b.ToList();をコメントを入れ替えました。
    さらにpublic ObservableCollection<binList> binLists { get; set; } を
    以下のように変更しました。
    private IList<binList> _binLists;
    public IList<binList> binLists
    {
    get { return _binLists; }
    set
    {
    if (_binLists != value)
    {
    _binLists = value;
    OnPropertyChanged("binLists");
    }
    }
    }

    更に以下のようにTwoWayを追加いたしました。
    ItemsSource="{Binding binLists, Mode=TwoWay}"

    期待通りに表示させることができました。

    諸先輩に追いつきたく何とかコードビハインドしないようにし、そのメリットを理解したいと思っていますが『コードビハインドに書いたほうが多分短いよな!』と思いながら苦慮しています。
    ありがとうございました。

    キャンセル

  • 2017/02/15 12:25

    MVVMアプローチは、UIが複雑化、アプリケーションが巨大化したとき発揮するので、かんたんなサンプル程度だと、回りくどいことをしているものになりますね。
    今時は、JSに、Vue.jsなどを導入しないとだめということがよくいわれるので、昔よりは、やるモチベーションを高められるのじゃないのでしょうか。(やりたいことは同じです)

    キャンセル

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

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

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

  • C#

    9290questions

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