如何在 WPF 组合框中使用多重绑定

发布于 2024-08-19 21:19:20 字数 2913 浏览 11 评论 0原文

这让我发疯!

我有一个 ComboBox 用于按员工过滤查询,该查询工作正常,但仅显示员工的名字。我想使用 MultiValueConverter 来显示员工的全名(如果我们没有 2 个 Mike 和 2 个 Daves,这就不那么紧急)

下面是我的工作代码和 IMultiValueConverter > 类(为简洁起见,删除了不必要的格式)。我已经尝试了所有我能想到的方法来让 MultiConverter 工作,但我没有运气。

<ComboBox ItemsSource="{Binding Path=EmployeesFilter}" 
                       DisplayMemberPath="EmpFirstName"
                       SelectedValue="{Binding Path=EmployeeToShow, Mode=TwoWay}"/>

它绑定到的 ViewModel 属性:

// This collection is used to populate the Employee Filter ComboBox
private ObservableCollection<Employee> employeesFilter;
public ObservableCollection<Employee> EmployeesFilter
{
    get {
            return employeesFilter;
        }
    set {
        if (employeesFilter != value)
        {
            employeesFilter = value;
            OnPropertyChanged("EmployeesFilter");
        }
    }
}

// This property is TwoWay bound to the EmployeeFilters SelectedValue
private Employee employeeToShow;
public Employee EmployeeToShow
{
    get {
            return employeeToShow;
        }
    set {
        if (employeeToShow != value)
        {
            employeeToShow = value;
            OnPropertyChanged("EmployeeToShow");
            QueryIssues(); // Requery with new employee filter
        }
    }
}

IMultiValueConverter:

class StringsToFullNameMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, 
                          Type targetType, 
                          object parameter, 
                          System.Globalization.CultureInfo culture)
    {
        // I added this because I kept getting DependecyProperty.UnsetValue 
        // Passed in as the program initializes
        if (values[0] as string != null)
        {
            string firstName = (string)values[0];
            string lastName = (string)values[1];
            string fullName = firstName + " " + lastName;
            return fullName;
        }
        return null;
    }

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

我尝试了很多不同的东西,但基本上在 ComboBox 中使用以下内容

<ComboBox.SelectedValue>
     <MultiBinding Converter="{StaticResource StringsToFullNameMultiConverter}" 
                   Mode="OneWay" > 
           <Binding Path="EmpFirstName" />
           <Binding Path="EmpLastName"/>
     </MultiBinding>
</ComboBox.SelectedValue>

按现在的情况,当程序使用设置为 DependencyProperty.UnsetValue 的值进行初始化时,将调用转换器。此后,即使您从框中选择了一个名称,它也不会再被调用。这些名称仍显示为名字。

感谢您提供的任何帮助或指向好的教程/示例的指示。我在网上找到的所有内容都是用于文本框的,我可以整天使用它们。

This is driving me NUTS!!!

I have a ComboBox used to filter a query by employee which works fine but only displays the employees first name. I want to use a MultiValueConverter to display the employees full name (This would be less urgent if we did not have 2 Mikes and 2 Daves)

Below is my working code and the IMultiValueConverter Class (With unnecessary formatting trimmed out for brevity). I have tried everything I can think of to get the MultiConverter to work but I have had no luck.

<ComboBox ItemsSource="{Binding Path=EmployeesFilter}" 
                       DisplayMemberPath="EmpFirstName"
                       SelectedValue="{Binding Path=EmployeeToShow, Mode=TwoWay}"/>

The ViewModel Properties it is bound to:

// This collection is used to populate the Employee Filter ComboBox
private ObservableCollection<Employee> employeesFilter;
public ObservableCollection<Employee> EmployeesFilter
{
    get {
            return employeesFilter;
        }
    set {
        if (employeesFilter != value)
        {
            employeesFilter = value;
            OnPropertyChanged("EmployeesFilter");
        }
    }
}

// This property is TwoWay bound to the EmployeeFilters SelectedValue
private Employee employeeToShow;
public Employee EmployeeToShow
{
    get {
            return employeeToShow;
        }
    set {
        if (employeeToShow != value)
        {
            employeeToShow = value;
            OnPropertyChanged("EmployeeToShow");
            QueryIssues(); // Requery with new employee filter
        }
    }
}

The IMultiValueConverter:

class StringsToFullNameMultiConverter : IMultiValueConverter
{
    public object Convert(object[] values, 
                          Type targetType, 
                          object parameter, 
                          System.Globalization.CultureInfo culture)
    {
        // I added this because I kept getting DependecyProperty.UnsetValue 
        // Passed in as the program initializes
        if (values[0] as string != null)
        {
            string firstName = (string)values[0];
            string lastName = (string)values[1];
            string fullName = firstName + " " + lastName;
            return fullName;
        }
        return null;
    }

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

I tried a lot of different things but basically am using the following in the ComboBox

<ComboBox.SelectedValue>
     <MultiBinding Converter="{StaticResource StringsToFullNameMultiConverter}" 
                   Mode="OneWay" > 
           <Binding Path="EmpFirstName" />
           <Binding Path="EmpLastName"/>
     </MultiBinding>
</ComboBox.SelectedValue>

As it stands now the converter is called when the program initializes with the values set to DependencyProperty.UnsetValue. after that it is never called again, even when you select a name from the box. The names are still displayed as a first name.

Thanks for any help or pointers to good tutorials/samples you can provide. All the ones I keep finding on the web are for textboxes and I can use them just fine all day.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不如归去 2024-08-26 21:19:20

你很接近了!不过,您想要做的是 ComboBox.ItemTemplate,而不是 SelectedValue。为 XAML 地狱做好准备。

<ComboBox.ItemTemplate>
    <DataTemplate>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource StringsToFillNameMultiConverter}">
                    <Binding Path="EmpFirstName" />
                    <Binding Path="EmpLastName" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </DataTemplate>
</ComboBox.ItemTemplate>

另外,如果我没记错的话,如果您只是格式化字符串,则不需要创建自己的转换器。我认为你可以执行以下操作(如果我错了,请有人纠正我。)

<!-- "Last, First" -->
<MultiBinding StringFormat="{}{1}, {0}">
    <Binding Path="EmpFirstName" />
    <Binding Path="EmpLastName" />
</MultiBinding>

You're close! What you want to do though is ComboBox.ItemTemplate, not SelectedValue. Prepare for some XAML hell.

<ComboBox.ItemTemplate>
    <DataTemplate>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource StringsToFillNameMultiConverter}">
                    <Binding Path="EmpFirstName" />
                    <Binding Path="EmpLastName" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </DataTemplate>
</ComboBox.ItemTemplate>

Also, if I recall correctly, you don't need to create your own converter if you're just formatting strings. I think you can do the following (someone please correct me if I'm wrong.)

<!-- "Last, First" -->
<MultiBinding StringFormat="{}{1}, {0}">
    <Binding Path="EmpFirstName" />
    <Binding Path="EmpLastName" />
</MultiBinding>
风筝有风,海豚有海 2024-08-26 21:19:20

您可能最好对项目使用数据模板,这样您就可以完全控制每个人在下拉列表中的显示方式。

只要您不需要控制不同字段的格式,类型转换就可以。

You may be better of using a data template for the items, so you have complete control over how each person is displayed in the dropdown list.

The type convert is OK provided you don’t have a need to control the formatting of the different fields.

陌上青苔 2024-08-26 21:19:20

我最终向我的类添加了一个只读属性,并在组合框中使用 Displaymemberpath

public class MyEmployee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string DisplayName {
    get { return FirstName + " " + LastName; }
        }
}

这样的东西适合您的情况吗...?
BR,
丹尼尔

I ended up by addig a Readonly Property to my Class and use Displaymemberpath in the Combobox

public class MyEmployee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string DisplayName {
    get { return FirstName + " " + LastName; }
        }
}

Could something like this work for your situation...?
BR,
Daniel

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文