简而言之,我的应用程序的一部分包含一系列绑定到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会正确填充。我在下面的问题区域中列出了解决方案:
答案 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>
截图