0

我的 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 绑定到多个字段?

4

3 回答 3

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

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

于 2013-02-21T14:36:33.817 回答
0

我认为将 MultiBinding 与 MultiValueConverter 一起使用应该可以为您解决问题。请参阅此 MSDN 页面上的示例

该示例显示如何将 text 属性绑定到从 2 个绑定属性 FirstName 和 LastName 计算的值

<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 是您想要获取/设置回商店的内容。例如,您可以向用户显示“电话号码,分机”,但在选择更改时,只会修改电话分机值。

于 2013-02-21T14:44:51.190 回答
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>

请注意,我使用了MultibindingCellTemplate(在查看模式下获取或设置单元格的数据模板)和CellEditTemplate(在编辑模式下获取或设置单元格的数据模板)。由于我的时间不多了,我让代码自己说话。如果您需要澄清,请发表评论,如果这太令人困惑,请发布新的 Stack Overflow 问题。我非常感谢 SO 社区。你摇滚!

于 2013-02-21T21:00:31.623 回答