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

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

ただいまの
回答率

89.13%

ComboBoxの選択中の値をListBoxに表示する方法

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,240

dai49

score 12

C#を勉強している初心者です。
下記サイトのコードを参考にしていて、試しに選択中のものをListBoxに表示させようとしたとき上手くいかずに詰まってしまったので質問させていただきました。
https://social.msdn.microsoft.com/Forums/ja-JP/c21a0bf4-46b8-4273-a810-255320d0ad3d/combobox12398369842524620013123982051612434viewmodel1236312425353732?forum=wpfja

ラベルに表示される内容と同じものをListBoxに表示させようとしましたが、1文字1文字分割されて数行で表示されてしまいます。
これを一行で表示する、コレクションの別の値を複数表示させるにはどのようにしたらいいのか分かる方ご教示ください。
よろしくお願いいたします。

<Window x:Class="WpfTest1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfTest1"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="360" Name="UI">

    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <ComboBox  x:Name="Maker" Margin="16"
                    ItemsSource="{Binding Path=Items}" SelectedItem="{Binding Path=Item,Mode=TwoWay}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=Name}" Width="100"/>
                        <TextBlock Text="{Binding Path=TEL}"/>
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
        <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="16">
            <TextBlock Text="担当者:"/>
            <TextBlock Text="{Binding ElementName=Maker, Path=SelectedItem.Tantou}"/>
        </StackPanel>
        <ListBox x:Name="ListBox1" ItemsSource="{Binding ElementName=Maker, Path=SelectedItem.Tantou}" HorizontalAlignment="Left" Height="69" Margin="123,10,0,0" Grid.Row="2" VerticalAlignment="Top" Width="78">
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;

namespace WpfTest1
{
  class Maker
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string TEL { get; set; }
        public string Tantou { get; set; }  //担当者
    }

    class MainWindowViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<Maker> items = new ObservableCollection<Maker>();
        public ObservableCollection<Maker> Items
        {
            get { return items; }
            set { items = value; }
        }

        private Maker item;
        public Maker Item
        {
            get { return item; }
            set
            {

                if (item == value) return;
                item = value;
                NotifyPropertyChanged("Item");
            }
        }

        public MainWindowViewModel()
        {
            //初期値
            items = new ObservableCollection<Maker>{
                new Maker{Id=1,Name="YAMAHA",TEL="06-9931-1584",Tantou="紺野佐吉,堀江明里"},
                new Maker{Id=2,Name="NEC",TEL="07-903-6820",Tantou="古屋冨士夫,大江薫"},
                new Maker{Id=3,Name="バッファロー",TEL="0885-40-6796",Tantou="国分七美,宮坂理香"},
                new Maker{Id=4,Name="エレコム",TEL="02-2748-8396",Tantou="日比野美香,渡辺徳雄"},
                new Maker{Id=5,Name="IODATA",TEL="098-333-1626",Tantou="神谷基一,望月幸彦"},
                new Maker{Id=6,Name="Cisco",TEL="04-0380-5406",Tantou="岩渕和歌,三村国男"},
                new Maker{Id=7,Name="NetGear",TEL="024-450-5136",Tantou="鎌田絵理,細谷彩香"}
            };
        }


        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

※追記
下記の画像のような表示を考えています。
イメージ説明

papinianus様にご提示いただいたコードでイメージしていた表示になりました。
他にもこんなやり方あるよという方いましたらご教示ください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • papinianus

    2019/01/30 10:38

    ListBoxは複数のものを入れるためのものなんで、文字列をバインドしちゃうと、自動的に文字が複数あるんだなと思ってしまうんですが、どうしてもListBoxじゃないといけませんか?

    キャンセル

  • dai49

    2019/01/30 11:31

    回答ありがとうございます。
    それで1文字ずつ表示されてしまっていたんですね。
    コレクションの各プロパティを一行ずつ表示できるイメージでした。
    ListBox 以外だとどのような方法がありますか?

    キャンセル

  • papinianus

    2019/01/30 11:34 編集

    方法というか、ユーザインターフェイスなので、何に出したいか、じゃないしょうか。絶対に1つしかない選択値をリストとして表示するのはユーザインターフェイスとしてあまり良いと思えないです。既存コードのままテキストボックス(テキストボックスを複数用意するの意味です)ではダメなのでしょうか。というか、勉強のステップとして、何が目的なのでしょう?

    キャンセル

  • dai49

    2019/01/30 14:56

    参考にさせていただいたコードだとTextBlockにTantouしか表示できませんが、目標は選択された項目のIDやNameなどの複数の値をListBoxのような複数選択できるようなコントロールに表示し、さらにそこで選択された値を別のメソッドに渡すような動きを考えています。

    キャンセル

回答 2

checkベストアンサー

0

質疑の↓に対する回答

参考にさせていただいたコードだとTextBlockにTantouしか表示できませんが、目標は選択された項目のIDやNameなどの複数の値をListBoxのような複数選択できるようなコントロールに表示し、さらにそこで選択された値を別のメソッドに渡すような動きを考えています。

正直そんなUI見たことないし、やめたほうがいいです
(特殊ってことは、サンプルや適切な参考書が見つからないってことですし、苦労して作ってもユーザは使いにくくて、何のために苦労するのか訳わからないです。ちなみにそういうオレオレインターフェイスを持つ製品の保守開発した経験から申し上げています)

どうしてもやりたいなら、まずクラス定義でそういうプロパティを作って

  class Maker
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string TEL { get; set; }
        public string Tantou { get; set; }  //担当者
        public string Selection { get => new []{Name, TEL, Tantou}; } //これな
    }


xamlのバインディングで、Pathを今つくったやつ(Selection)にすればいいと思う

<ListBox x:Name="ListBox1" ItemsSource="{Binding ElementName=Maker, Path=SelectedItem.Selection}" HorizontalAlignment="Left" Height="69" Margin="123,10,0,0" Grid.Row="2" VerticalAlignment="Top" Width="78">

動作検証してませんが。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/31 11:39

    ありがとうございます。
    いただいたコードでListBoxに表示することができました。

    追加で質問させていただきたいのですが、Selectionで表示させたいプロパティを明示していますがitemsの各要素全部表示するといったことは可能でしょうか?

    キャンセル

  • 2019/01/31 12:02

    意図が曖昧です。
    1. class Makerのプロパティが増えたときに(新しい項目が増えたときに)自動でという意味ですか?
    2. MainWindowViewModel.itemsに格納された複数のメーカ情報を全部列挙という意味ですか?

    いずれにしても、どちらも可能です。
    1. リフレクションを使えばできますが、私個人の考えとして、明示できるものは明示すべきと考えます。自分でクラス定義をしているのですから、明示できないはずがないです。クラス定義がかわればアセンブリが更新されます。そこだけ手抜きする意味が全く分かりません。そういうのが嫌だったら最初からC#(静的型言語)はやめたほうがいいと思います。
    2. それはもはやMakerのやることじゃないです。ViewModelに別途プロパティを持つことになります。しかしながら、そこで列挙されるものは上のリストボックスにあるので、それを展開するっていうのが良く分からないです。仮に"yamaha"と"nec"と"02-2748-8396"(エレコムの電話番号)が選択されたときに、一体全体どういう処理をしたいのでしょうか。そのような、なんでもかんでもつっこんだごった煮からできることなんてありません。IDがint型なんでSelectionには入れていませんが、仮にIDはそこに入ってしまうと、数値に戻す処理がなければ何もしようがないものです。

    プログラムを書けば大抵のことはできます。しかし、何の利用価値もなく、誰も嬉しくないような、賽の河原の石積みをする気は私はありません。

    何がしたいのか分かりませんが、うっすら想定するところではDataGridあたりから調べ直したほうがよいように思います。

    キャンセル

0

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/01/31 11:53

    回答ありがとうございます。
    ComboBoxで名前を指定したらご提示いただいたサイトのプロパティ画像で書かれている各項目を紐づいている分だけListBoxに一覧で表示させたい感じです。
    イメージしているものを追記しましたので見ていただけると幸いです。

    キャンセル

  • 2019/01/31 11:57

    リストボックスではなくユーザーコントロールを作るのがいいと思います。

    キャンセル

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

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