如何将GridViewComboBoxColumn绑定到多个字段?

时间:2013-02-21 14:03:30

标签: c# wpf xaml data-binding telerik

我的GridViewComboBox ItemsSource是一个可观察的联系人集合。它在两列中显示FullName和PhoneExtension。组合框是我的Telerik WPF RadGridView中的一列。 GridViewComboBoxColumn(不工作)xaml如下所示:

<telerik:GridViewComboBoxColumn Name="contactsComboBox"  Header="Contact"
   DisplayMemberPath="FullName"
   SelectedValueMemberPath="FullName"
   ItemsSource="{Binding ContactListObservable}"
   DataMemberBinding="{Binding PhoneExtension}" >

    <telerik:GridViewComboBoxColumn.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition  Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>

                <TextBlock Text="{Binding FullName}" />
                <TextBlock Text="    Phone: "  Grid.Column="1" />
                <TextBlock Text="{Binding PhoneExtension}"  Grid.Column="2" />
            </Grid>
        </DataTemplate>
    </telerik:GridViewComboBoxColumn.ItemTemplate>
</telerik:GridViewComboBoxColumn>

我想绑定FullName和PhoneExtension,但似乎我只能在DataMemberBinding中有一个字段。我不确定DisplayMemberPath或SelectedValueMemberPath中的内容。

我也愿意使用事件而不是绑定。如果您可以同时显示AddHandler和组合框的SelectionChangedEvent的代码,那将非常感激。

如何将多列GridViewComboBox绑定到多个字段?

3 个答案:

答案 0 :(得分:0)

嗨,一种方法是重写ToString()方法,另一种方法是使用Converter。

    public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Students = new ObservableCollection<Student>();
        Students.Add(new Student() { Name = "abc", RollNo = 1, Course = "MCA" });
        Students.Add(new Student() { Name = "xyz", RollNo = 1, Course = "MCA" });
        Students.Add(new Student() { Name = "pqr", RollNo = 1, Course = "MCA" });
        Students.Add(new Student() { Name = "stu", RollNo = 1, Course = "MCA" });
    }
    public ObservableCollection<Student> Students { get; set; }
}

public  class Student
{
    public string Name { get; set; }
    public string Course  { get; set; }
    public int RollNo { get; set; }

    public override string ToString()
    {
        return this.Name + "  " + this.Course;
    }
}

<ComboBox ItemsSource="{Binding Students}"/>

另一种方法是使用转换器

    public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {

        if (value is Student)
            return ((Student)value).Name + "  " + ((Student)value).Course;
        else
            return null;

    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我希望这会给你一个想法。

答案 1 :(得分:0)

我认为将MultiBinding与MultiValueConverter一起使用应该可以帮到你。请参阅this MSDN page

上的示例

该示例显示如何将text属性绑定到从2个绑定属性FirstName&amp;名字

<telerik:GridViewComboBoxColumn  
                    ItemsSource="{Binding}">
   <telerik:GridViewComboBoxColumn.DisplayMemberBinding>
      <MultiBinding Converter="{StaticResource myNameConverter}"
                  ConverterParameter="FormatLastFirst">
         <Binding Path="FullName"/>
         <Binding Path="PhoneExt"/>
      </MultiBinding>  
   </telerik:GridViewComboBoxColumn.DisplayMemberBinding>

DisplayMemberBinding看起来就像您希望组合框下拉显示的那样。 DataMemberBinding是您希望获取/设置回商店的内容。例如您可以向用户显示“电话号码,分机号码”,但在选择更改时,只会修改PhoneExt值。

答案 2 :(得分:0)

以下是我如何解决这个问题(我正在回答我自己的问题)。

首先是我使用的Multibinding TypeConverters:

public class CombineFullNameAndPhoneExtensionMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values,
                          Type targetType,
                          object parameter,
                          System.Globalization.CultureInfo culture)
    {
        if (values[0] as string != null)
        {
            string fullName = (string)values[0] ?? "Unknown";
            string phoneExtension = (string)values[1] ?? "Unknown";
            string namePlusExtension = fullName.Trim() + "    Phone: " + phoneExtension.Trim();
            return namePlusExtension;
        }
        return null;
    }

    public object[] ConvertBack(object value,
                                Type[] targetTypes,
                                object parameter,
                                System.Globalization.CultureInfo culture)
    {
        NotesContact c = (NotesContact)value;

        string[] returnValues = { c.FullName.Trim(), c.PhoneExtension.Trim() };
        return returnValues;
    }
}

public class CombineLastNameFirstNameAndPhoneExtensionMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values,
                         Type targetType,
                         object parameter,
                         System.Globalization.CultureInfo culture)
   {
       if (values[0] as string != null)
       {
           string lastName = (string)values[0] ?? "Unknown";
           string firstName = (string)values[1] ?? "Unknown";
           string phoneExtension = (string)values[2] ?? "Unknown";

           string lastCommaFirstPlusExtension = lastName.Trim() + ", " + firstName.Trim() + "    Phone: " + phoneExtension.Trim();
           return lastCommaFirstPlusExtension;
       }
       return null;
   }

   public object[] ConvertBack(object value,
                               Type[] targetTypes,
                               object parameter,
                               System.Globalization.CultureInfo culture)
   {
       throw new NotImplementedException();
   }
}

以下是xaml中的Converter声明:

<local:CombineFullNameAndPhoneExtensionMultiConverter x:Key="combinedFullNameAndPhoneExtensionConverter"/>
<local:CombineLastNameFirstNameAndPhoneExtensionMultiConverter x:Key="combinedLastNameFirstNameAndPhoneExtensionConverter"/>

现在这里是ComboBox xaml:

<telerik:GridViewComboBoxColumn Name="contactsGridViewComboBox"  Header="Contact"
        ItemsSource="{Binding ContactListObservable, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
<telerik:GridViewComboBoxColumn.CellTemplate>
    <DataTemplate>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding  Converter="{StaticResource combinedFullNameAndPhoneExtensionConverter}">
                        <Binding Path="FullName"/>
                        <Binding Path="PhoneExtension"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </DataTemplate>
</telerik:GridViewComboBoxColumn.CellTemplate>
<telerik:GridViewComboBoxColumn.CellEditTemplate>
    <DataTemplate x:Name="ContactsCellEditTemplate">
        <Grid FocusManager.FocusedElement="{Binding ElementName=ContactsTemplateComboBox}">
            <telerik:RadComboBox x:Name="ContactsTemplateComboBox" IsSynchronizedWithCurrentItem="False" IsEditable="False" ItemsSource="{Binding ContactListObservable, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"  IsDropDownOpen="True" TextSearchMode="Contains" IsFilteringEnabled="True" OpenDropDownOnFocus="True">
                <telerik:RadComboBox.SelectedItem>
                    <MultiBinding Converter="{StaticResource combinedFullNameAndPhoneExtensionConverter}">
                        <Binding Path="FullName" UpdateSourceTrigger="PropertyChanged"/>
                        <Binding Path="PhoneExtension" UpdateSourceTrigger="PropertyChanged"/>
                    </MultiBinding>
                </telerik:RadComboBox.SelectedItem>
                <telerik:RadComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock DataContext="{Binding}">
                            <TextBlock.Text>                                                        
                                <MultiBinding  Converter="{StaticResource combinedLastNameFirstNameAndPhoneExtensionConverter}">                             
                                    <Binding Path="LastName"/>                                                                                                                                                             <Binding Path="FirstName" />
                                    <Binding Path="PhoneExtension"/>
                                </MultiBinding>
                            </TextBlock.Text>
                        </TextBlock>
                    </DataTemplate>
                </telerik:RadComboBox.ItemTemplate>
            </telerik:RadComboBox>
        </Grid>
    </DataTemplate>
</telerik:GridViewComboBoxColumn.CellEditTemplate>

注意我已经使用 Multibinding CellTemplate (在视图模式下获取或设置单元格的数据模板)和 CellEditTemplate (在编辑模式下获取或设置单元格的数据模板)。因为我已经没时间了,所以我让代码说出来。如果您需要澄清或发布新的Stack Overflow问题,请留下评论,如果这太混乱了。我非常感谢SO社区。你摇滚!