簡體   English   中英

c#wpf組合框將源綁定到一個集合,並將項作為另一個集合的屬性

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

我試圖將comboboxitemssource綁定到對象( Source1 )集合的屬性,再DataGridTemplateColumnDataGridDataGridTemplateColumn中另一個對象( MyCollection )的屬性:

視圖:

<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(模型(包括其余的視圖類)):

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)); }
        }


    }
}

最后是Source1類:

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

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

和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;
        }
    }
}

當我運行此程序時,我得到了錯誤和建議,以為Source1創建一個轉換器到System.Int32 我認為ComboBoxSelectedValue="{Binding Age}"會將MyClass的年齡連接到DisplayedMemberPath 是否可以通過這種方式連接兩個不同類的兩個屬性,還是有必要創建一個轉換器? 我想創建一個read-only屬性,該屬性將使用Linq從Source1集合中返回Source1.Number的列表, Source1.Number其用作comboboxItemssource ,但我想知道與使用轉換器相比,這是否是不好的做法?

我認為您的問題是因為您沒有在組合中設置所需的所有屬性。

嘗試

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

Source1可能只有一個屬性,但是組合框不是智能的,因此它試圖將一個int設置為Source1的一個實例,而不是一個int。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM