无法让DisplayMemberPath在列表框中显示绑定的对象数据

时间:2012-10-07 01:47:17

标签: c# wpf data-binding listboxitem ivalueconverter

简而言之,我的应用程序的一部分包含一系列绑定到Xaml中对象实例的列表框。使用IValueConverter,我能够从主对象中检索<Part>个对象的列表,并显示检索到的对象的.ToString()形式。但是,我想要做的是显示对象的Name属性。我将DisplayMemberPath设置为Name,但结果只会消除listboxitem。我已经发布了以下代码的相关部分:

XAML:

<Window.Resources>
    <local:LocationtoEquipmentCOnverter x:Key="locationEquipmentFiller" />
</Window.Resources>
<Window.DataContext>
    <local:MegaWdiget/>
</Window.DataContext>
<ListBox x:Name="listboxFront" HorizontalAlignment="Left" Margin="180,45,0,0" VerticalAlignment="Top" Width="82" Opacity="0.5" ItemsSource="{Binding ConverterParameter=Front, Converter={StaticResource locationEquipmentFiller}, Mode=OneWay}" DisplayMemberPath="Name"/>

ValueConverter:

public class LocationtoEquipmentCOnverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        MegaWidget MWidget = (MegaWidget)value;
        Location loc = MWidget.Locations[(string)parameter];
        return loc.Contents;
    }

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

MegaWidget对象包含以下内容:

[XmlElement]
public Dictionary<string, Location> Locations { get; set; }

Location Object包含一个List,其中包含我需要查询其名称的实际对象:

 public List<Part> Contents;

找到解决方案

在继续Mate推荐的故障排除之后,我发现传递的对象是Part对象而不是ListBoxItems。这导致ListBox填充实际对象而不是ListBoxItems。通过更改ValueConverter以传递List ListBoxItems并将内容标记设置为我需要的内容,ListBox会正确填充。我在下面的问题区域中列出了解决方案:

3 个答案:

答案 0 :(得分:2)

在继续Mate推荐的故障排除之后,我发现传递的对象是Part对象而不是ListBoxItems。这导致ListBox被填充实际对象而不是ListBoxItems。通过更改ValueConverter以传递ListBoxItems List并将内容标记设置为我需要的内容,ListBoxes正确填充。

新的ValueConverter:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    MegaWidget MWidget = (MegaWidget)value;
    Location loc = MWidget.Locations[(string)parameter];
    List<ListBoxItem> displayContent = new List<ListBoxItem>();

    foreach (Part item in loc.Contents)
    {
        ListBoxItem lbi = new ListBoxItem();
        lbi.Content = item.Name;
        displayContent.Add(lbi);
    }

    return displayContent;
}

答案 1 :(得分:1)

根据你的回答“如果我不添加DisplayMemberPath,但显示继承(system.MWidget.Part)”,我认为属性Name是空的。

要检查,请测试:

public class LocationtoEquipmentCOnverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,   System.Globalization.CultureInfo culture)
    {
        MegaWidget MWidget = (MegaWidget)value;
        Location loc = MWidget.Locations[(string)parameter];

        //Refers to Class "Content" used in loc.Contents collection. I do not know what the name that you have used
        foreach (Content item in loc.Contents)
        {
            item.Name += "***";
        }

        return loc.Contents;
    }

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

答案 2 :(得分:0)

这里有一个示例

  • 模型

    public class MegaWidget
    {
        public Dictionary<string, Location> Locations { get; set; }
    }
    
    public class Location
    {
        public List<Part> Contents { get; set; }
    }
    
    public class Part
    {
        public int Id { get; set; }
        public string PartName { get; set; }
    }
    
  • 转换器

    public class LocationEquipmentConverter : IValueConverter
    {
        public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
        {
            MegaWidget widget = value as MegaWidget;
            string location = (string) parameter;
            return widget?.Locations[ location ]?.Contents;
        }
    
        public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
        {
            throw new NotImplementedException( );
        }
    }
    
  • 视图模型

    public class FooViewModel : ViewModelBase
    {
        public FooViewModel()
        {
            Widget = new MegaWidget
            {
                Locations = new Dictionary<string, Location>
                {
                    [ "Front" ] = new Location
                    {
                        Contents = new List<Part>
                        {
                            new Part { Id = 1, PartName = "Part 01" },
                            new Part { Id = 2, PartName = "Part 02" },
                            new Part { Id = 3, PartName = "Part 03" },
                        }
                    },
                    [ "Back" ] = new Location
                    {
                        Contents = new List<Part>
                        {
                            new Part { Id = 11, PartName = "Part 11" },
                            new Part { Id = 12, PartName = "Part 12" },
                            new Part { Id = 13, PartName = "Part 13" },
                        }
                    },
                }
            };
        }
    
        public MegaWidget Widget { get; }
    
        #region Property FrontPart
        private Part _frontPart;
    
        public Part FrontPart
        {
            get { return _frontPart; }
            set { SetProperty( ref _frontPart, value ); }
        }
        #endregion
    
        #region Property BackPart
        private Part _backPart;
    
        public Part BackPart
        {
            get { return _backPart; }
            set { SetProperty( ref _backPart, value ); }
        }
        #endregion
    }
    
  • 查看

    <Window x:Class="WPG.WpfApp.FooView"
            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:ViewModel="clr-namespace:WPG.WpfApp.ViewModel"
            xmlns:local="clr-namespace:WPG.WpfApp"
            mc:Ignorable="d"
            Title="FooView" Height="300" Width="300">
        <Window.Resources>
            <ViewModel:LocationEquipmentConverter x:Key="LocationEquipmentConverter"/>
        </Window.Resources>
        <Window.DataContext>
            <ViewModel:FooViewModel/>
        </Window.DataContext>
        <Grid>
            <StackPanel>
                <ListBox ItemsSource="{Binding Widget, ConverterParameter=Front, Converter={StaticResource LocationEquipmentConverter}, Mode=OneWay}"
                         SelectedItem="{Binding Path=FrontPart}"
                         DisplayMemberPath="PartName"/>
                <ListBox ItemsSource="{Binding Widget, ConverterParameter=Back, Converter={StaticResource LocationEquipmentConverter}, Mode=OneWay}"
                         SelectedItem="{Binding Path=BackPart}"
                         DisplayMemberPath="PartName"/>
            </StackPanel>
        </Grid>
    </Window>
    
  • 截图

enter image description here

相关问题