web-dev-qa-db-ja.com

MVVMを使用したComboBox SelectedItemのバインド

ComboBoxSelectedItemに問題があります。

<ComboBox Name="cbxSalesPeriods"
        ItemsSource="{Binding SalesPeriods}"
        DisplayMemberPath="displayPeriod"
        SelectedItem="{Binding SelectedSalesPeriod}"
        SelectedValuePath="displayPeriod"
        IsSynchronizedWithCurrentItem="True"/>

Here is anything ok ComboBoxを開くと、値が表示されます。

enter image description here アイテムを選択した場合、選択したアイテムは表示されません。

誰もがアイデアを持っていますか?

私のViewModelには、次の2つのプロパティがあります。

public ObservableCollection<SalesPeriodVM> SalesPeriods { get; private set; }

private SalesPeriodVM selectedSalesPeriod;
public SalesPeriodVM SelectedSalesPeriod
{
    get { return selectedSalesPeriod; }

    set 
    {
        if (selectedSalesPeriod != value)
        {
            selectedSalesPeriod = value;
            RaisePropertyChanged("SelectedSalesPeriod");
        }
    }
}

これらはクラスのいくつかのプロパティです:

public SalesPeriodVO Vo
{
    get { return period; }
}

public int Year
{
    get { return period.Year; }
    set
    {
        if (period.Year != value)
        {
            period.Year = value;
            RaisePropertyChanged("Year");
        }
    }
}

public int Month
{
    get { return period.Month; }
    set
    {
        if (period.Month != value)
        {
            period.Month = value;
            RaisePropertyChanged("Month");
        }
    }
}

public string displayPeriod { 
    get
    {
        return this.ToString();
    }
}

public override string ToString()
{
    return String.Format("{0:D2}.{1}", Month, Year);
}

[〜#〜] edit [〜#〜]:DisplayMemberPathプロパティを削除すると、次のようになります。 enter image description here

29
René Winter

ComboBoxのプロパティを不必要に設定しているようです。異なる用途を持つDisplayMemberPathおよびSelectedValuePathプロパティを削除できます。これらのプロパティの説明については、 SelectedItem、SelectedValue、SelectedValuePathの違い をご覧ください。これを試して:

<ComboBox Name="cbxSalesPeriods"
    ItemsSource="{Binding SalesPeriods}"
    SelectedItem="{Binding SelectedSalesPeriod}"
    IsSynchronizedWithCurrentItem="True"/>

さらに、displayPeriodプロパティを使用しても意味がありません。WPFFrameworkは、ToStringが設定されていない表示する必要があるオブジェクトに対してDataTemplateメソッドを自動的に呼び出すためです。それらのために明示的に。


更新>>>

私はあなたのコードのすべてを見ることができないので、私はあなたが間違っていることをあなたに伝えることができません。代わりに、私ができることは、あなたが望むものを達成する方法の完全な実例を提供することです。私はそれについて何も知らないので、クラスから無意味なdisplayPeriodプロパティとSalesPeriodVOプロパティを削除しました...多分それがあなたの問題の原因ですか??。これを試して:

public class SalesPeriodV
{
    private int month, year;

    public int Year
    {
        get { return year; }
        set
        {
            if (year != value)
            {
                year = value;
                NotifyPropertyChanged("Year");
            }
        }
    }

    public int Month
    {
        get { return month; }
        set
        {
            if (month != value)
            {
                month = value;
                NotifyPropertyChanged("Month");
            }
        }
    }

    public override string ToString()
    {
        return String.Format("{0:D2}.{1}", Month, Year);
    }

    public virtual event PropertyChangedEventHandler PropertyChanged;
    protected virtual void NotifyPropertyChanged(params string[] propertyNames)
    {
        if (PropertyChanged != null)
        {
            foreach (string propertyName in propertyNames) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            PropertyChanged(this, new PropertyChangedEventArgs("HasError"));
        }
    }
}

次に、ビューモデルに2つのプロパティを追加しました。

private ObservableCollection<SalesPeriodV> salesPeriods = new ObservableCollection<SalesPeriodV>();
public ObservableCollection<SalesPeriodV> SalesPeriods
{
    get { return salesPeriods; }
    set { salesPeriods = value; NotifyPropertyChanged("SalesPeriods"); }
}
private SalesPeriodV selectedItem = new SalesPeriodV();
public SalesPeriodV SelectedItem
{
    get { return selectedItem; }
    set { selectedItem = value; NotifyPropertyChanged("SelectedItem"); }
}

次に、your値でコレクションを初期化しました。

SalesPeriods.Add(new SalesPeriodV() { Month = 3, Year = 2013 } );
SalesPeriods.Add(new SalesPeriodV() { Month = 4, Year = 2013 } );

そして、データ結合されたonlyこれら2つのプロパティはComboBoxに:

<ComboBox ItemsSource="{Binding SalesPeriods}" SelectedItem="{Binding SelectedItem}" />

それだけです...完璧に機能する例に必要なのはそれだけです。アイテムの表示はToStringメソッドwithoutdisplayPeriodプロパティからのものであることがわかります。うまくいけば、このコード例から間違いを解決できます。

43
Sheridan

コンボボックスで何かを選択したときにSelectedItem-bindingが更新されないという同様の問題がありました。私の問題は、バインディングにpdateSourceTrigger = PropertyChangedを設定しなければならなかったことです。

<ComboBox ItemsSource="{Binding SalesPeriods}" 
          SelectedItem="{Binding SelectedItem, UpdateSourceTrigger=PropertyChanged}" />
0
<!-- xaml code-->
    <Grid>
        <ComboBox Name="cmbData"    SelectedItem="{Binding SelectedstudentInfo, Mode=OneWayToSource}" HorizontalAlignment="Left" Margin="225,150,0,0" VerticalAlignment="Top" Width="120" DisplayMemberPath="name" SelectedValuePath="id" SelectedIndex="0" />
        <Button VerticalAlignment="Center" Margin="0,0,150,0" Height="40" Width="70" Click="Button_Click">OK</Button>
    </Grid>



        //student Class
        public class Student
        {
            public  int Id { set; get; }
            public string name { set; get; }
        }

        //set 2 properties in MainWindow.xaml.cs Class
        public ObservableCollection<Student> studentInfo { set; get; }
        public Student SelectedstudentInfo { set; get; }

        //MainWindow.xaml.cs Constructor
        public MainWindow()
        {
            InitializeComponent();
            bindCombo();
            this.DataContext = this;
            cmbData.ItemsSource = studentInfo;

        }

        //method to bind cobobox or you can fetch data from database in MainWindow.xaml.cs
        public void bindCombo()
        {
            ObservableCollection<Student> studentList = new ObservableCollection<Student>();
            studentList.Add(new Student { Id=0 ,name="==Select=="});
            studentList.Add(new Student { Id = 1, name = "zoyeb" });
            studentList.Add(new Student { Id = 2, name = "siddiq" });
            studentList.Add(new Student { Id = 3, name = "James" });

              studentInfo=studentList;

        }

        //button click to get selected student MainWindow.xaml.cs
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Student student = SelectedstudentInfo;
            if(student.Id ==0)
            {
                MessageBox.Show("select name from dropdown");
            }
            else
            {
                MessageBox.Show("Name :"+student.name + "Id :"+student.Id);
            }
        }
0
Zoyeb Shaikh