简体   繁体   中英

c# wpf combobox binding source to one collection and item as property of another collection

I am trying to bind the itemssource of a combobox to a property of a object ( Source1 ) collection to a property of another object ( MyCollection ) in a DataGridTemplateColumn in a DataGrid :

View:

<Window x:Class="TestWPF.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:TestWPF"
        mc:Ignorable="d"
        Title="Test WPF" Height="350" Width="525">
    <Window.DataContext>
        <local:ViewModel></local:ViewModel>
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Label Content="Testing DATAGRIDTEMPLATECOLUMN with COMBOBOX" FontFamily="Verdana" FontSize="16" Grid.Column="0" Grid.Row="0"/>
        <DataGrid Grid.Column="0" Grid.Row="1" ItemsSource="{Binding MyCollection}" CanUserAddRows="True" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Name}" Header="Name of person"/>
                <DataGridTemplateColumn Header="Age of person" >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Grid>
                                <ComboBox ItemsSource="{Binding Path=DataContext.Source1,
                                        RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"
                                              SelectedValue="{Binding Age}" DisplayMemberPath="Number"/>
                            </Grid>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn Binding="{Binding Salary}" Header="Persons salary"/>
            </DataGrid.Columns>
        </DataGrid>
        <!-- Just for checking -->
        <DataGrid Grid.Column="0" Grid.Row="2" ItemsSource="{Binding MyCollection}" CanUserAddRows="True" AutoGenerateColumns="True"/>
    </Grid>
</Window>

ViewModel (model (including rest of view class)):

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

namespace TestWPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ViewModel vm;
        public MainWindow()
        {
            InitializeComponent();

        }


    }

    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }

        private ObservableCollection<MyClass> _myCollection;

        private ObservableCollection<Source1> _source1;

        public ObservableCollection<Source1> Source1
        {
            get { return _source1; }
            set { _source1 = value; }
        }


        public ViewModel()
        {
            _source1 = new ObservableCollection<TestWPF.Source1>();
            _myCollection = new ObservableCollection<MyClass>();
            SetupSource();

        }

        private void SetupSource()
        {
            _source1.Add(new TestWPF.Source1(2));
            _source1.Add(new TestWPF.Source1(3));
            _source1.Add(new TestWPF.Source1(5));
            _source1.Add(new TestWPF.Source1(8));
        }

        public ObservableCollection<MyClass> MyCollection
        {
            get { return _myCollection; }
            set { _myCollection = value; NotifyPropertyChanged(nameof(MyCollection)); }
        }


    }
}

And finally the Source1 class:

namespace TestWPF
{
    public class Source1
    {
        public int Number { get; set; }

        public Source1(int n)
        {
            Number = n;
        }
    }
}

and MyClass:

namespace TestWPF
{
    public class MyClass
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public double Salary { get; set; }

        public MyClass()
        {

        }
        public MyClass(string n, int a, double s)
        {
            Name = n;
            Age = a;
            Salary = s;
        }
    }
}

When I run this I get errors and advice to create a converter for the Source1 to System.Int32 . I thought that the SelectedValue="{Binding Age}" of the ComboBox would connect the age of MyClass to the DisplayedMemberPath . Is there a way to connect two properties of two different classes in this way or is it necessary to create a converter? I thought of creating a read-only property that would return a list of Source1.Number from the Source1 collection using Linq and use that as a Itemssource for the combobox but I wonder if this is bad practice compared to using a converter?

I think your problem is because you've not set all the properties you need to on your combo.

Try

<ComboBox ItemsSource="{Binding Path=DataContext.Source1,
          RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"
          SelectedValue="{Binding Age}"
          SelectedValuePath="Number" 
          DisplayMemberPath="Number"/>

Source1 may only have one property but the combobox isn't intelligent, so it's trying to set (Age) an int to an instance of Source1 rather than an int.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM