c#wpf combobox将source绑定到一个collection,item作为另一个collection的属性
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#wpf combobox将source绑定到一个collection,item作为另一个collection的属性相关的知识,希望对你有一定的参考价值。
我试图将itemssource
的combobox
绑定到对象(Source1
)集合的属性到MyCollection
的DataGridTemplateColumn
中的另一个对象(DataGrid
)的属性:
视图:
<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
。我认为SelectedValue="{Binding Age}"
的ComboBox
会将MyClass
的年龄与DisplayedMemberPath
联系起来。有没有办法以这种方式连接两个不同类的两个属性,还是有必要创建一个转换器?我想创建一个read-only
属性,它将使用Linq从Source1集合中返回Source1.Number
列表,并将其用作Itemssource
的combobox
,但我想知道与使用转换器相比这是不是很糟糕吗?
我认为你的问题是因为你没有在你的组合中设置你需要的所有属性。
尝试
<ComboBox ItemsSource="{Binding Path=DataContext.Source1,
RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}"
SelectedValue="{Binding Age}"
SelectedValuePath="Number"
DisplayMemberPath="Number"/>
Source1可能只有一个属性,但组合框不是智能的,所以它试图将(Age)一个int设置为Source1的实例而不是int。
以上是关于c#wpf combobox将source绑定到一个collection,item作为另一个collection的属性的主要内容,如果未能解决你的问题,请参考以下文章
C# WPF ComboBox - 排除绑定数据的最后一行(或空格)(从 Microsoft Access 绑定)