【코드 메모】 【WPF】 ComboBox에서 선택한 항목의 속성을 TextBox에 바인딩

15435 단어 MVVMWPFmemo
↓이 기사가 신경이 쓰였으므로 테스트
WPF의 바인딩에 대한 원인은 알지만 납득할 수없는 이야기

↓참고 기사
콤보 상자(ComboBox)에서 선택한 항목 가져오기(WPF)

※ Livet WPF4.5를 사용하고 있습니다만, 문제점에는 관계가 없다고 생각합니다.

MainWindow.xaml
<Window x:Class="training_ItemsControl.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
        xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
        xmlns:v="clr-namespace:training_ItemsControl.Views"
        xmlns:vm="clr-namespace:training_ItemsControl.ViewModels"
        Title="MainWindow" Height="350" Width="525">

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

    <i:Interaction.Triggers>

        <!--WindowのContentRenderedイベントのタイミングでViewModelのInitializeメソッドが呼ばれます-->
        <i:EventTrigger EventName="ContentRendered">
            <l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Initialize"/>
        </i:EventTrigger>

        <!--Windowが閉じたタイミングでViewModelのDisposeメソッドが呼ばれます-->
        <i:EventTrigger EventName="Closed">
            <l:DataContextDisposeAction/>
        </i:EventTrigger>

        <!--WindowのCloseキャンセル処理に対応する場合は、WindowCloseCancelBehaviorの使用を検討してください-->

    </i:Interaction.Triggers>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <ComboBox x:Name="ComboBox1" 
            ItemsSource="{Binding Persons}"  
            DisplayMemberPath="Name"  
            SelectedValuePath="Id" 
            Margin="5" />

        <!--ComboBoxのSelectedValuePathにオブジェクトのパスを設定しておくと、 
          SelectedValueで選択されたオブジェクトの指定パスの値が取得できる 
          複数選択された場合は先頭のオブジェクトの指定パスの値となる-->
        <TextBox Grid.Row="2" Margin="5" Text="{Binding SelectedValue, ElementName=ComboBox1}" />

        <!--ComboBoxのSelectedItemには選択されたオブジェクトが取得できる-->
        <TextBox Grid.Row="3" Margin="5" Text="{Binding SelectedItem.Name, ElementName=ComboBox1}" />

    </Grid>
</Window>

MainWindowViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.ComponentModel;

using Livet;
using Livet.Commands;
using Livet.Messaging;
using Livet.Messaging.IO;
using Livet.EventListeners;
using Livet.Messaging.Windows;

using training_ItemsControl.Models;

namespace training_ItemsControl.ViewModels
{
    public class MainWindowViewModel : ViewModel
    {
        public void Initialize()
        {
            this.Persons = new ObservableCollection<PersonViewModel>() {
                new PersonViewModel() { Id = 1, Name = "新宿 一郎" },
                new PersonViewModel() { Id = 2, Name = "初台 次郎" },
                new PersonViewModel() { Id = 3, Name = "大手町 三郎" },
                new PersonViewModel() { Id = 4, Name = "代田橋 四朗" },
                new PersonViewModel() { Id = 5, Name = "赤坂 五郎" },
            };
        }


        #region Persons変更通知プロパティ
        private ObservableCollection<PersonViewModel> _Persons;

        public ObservableCollection<PersonViewModel> Persons
        {
            get
            { return _Persons; }
            set
            { 
                if (_Persons == value)
                    return;
                _Persons = value;
                RaisePropertyChanged();
            }
        }
        #endregion

    }
}

PersonViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

using Livet;
using Livet.Commands;
using Livet.Messaging;
using Livet.Messaging.IO;
using Livet.EventListeners;
using Livet.Messaging.Windows;

using training_ItemsControl.Models;

namespace training_ItemsControl.ViewModels
{
    public class PersonViewModel : ViewModel
    {
        public void Initialize()
        {
        }


        #region Id変更通知プロパティ
        private int _Id;

        public int Id
        {
            get
            { return _Id; }
            set
            { 
                if (_Id == value)
                    return;
                _Id = value;
                RaisePropertyChanged();
            }
        }
        #endregion


        #region Name変更通知プロパティ
        private string _Name;

        public string Name
        {
            get
            { return _Name; }
            set
            { 
                if (_Name == value)
                    return;
                _Name = value;
                RaisePropertyChanged();
            }
        }
        #endregion

    }
}

↓퍼스 에러는 발생하지 않고, 문제 없게 바인드 할 수 있었습니다.

좋은 웹페이지 즐겨찾기