假设您有一个项目列表,每个项目都有Id和Name属性。然后你有一个字典(一个单独的属性),它将id映射到价格。
public partial class MainWindow : Window
{
private IEnumerable<Comic> issues = new List<Comic>
{
new Comic() {Id = 5, Name = "Issue 1"},
new Comic() {Id = 19, Name = "Issue 2"},
new Comic() {Id = 3, Name = "Issue 3"},
new Comic() {Id = 9, Name = "Issue 4"}
};
public Dictionary<int, decimal> Prices
{
get
{
return new Dictionary<int, decimal>()
{
{5, 10.55M},
{19, 5.00M},
{3, 19.45M},
{9, 287.74M}
};
}// end get
}// end property Prices
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
public IEnumerable<Comic> ExpensiveIssues
{
get
{
return issues;
}
}// end ExpensiveIssues()
}// end MainWindow
public class Comic
{
public int Id { get; set; }
public string Name { get; set; }
}
在用户界面中,您希望显示一个包含项目名称和价格的表格(按ID查找价格)。你会如何通过数据绑定来做到这一点?
<Window x:Class="LinqTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListView ItemsSource="{Binding ExpensiveIssues}" x:Name="viewNumbers" HorizontalAlignment="Left" Margin="137,52,0,0" VerticalAlignment="Top">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Issue Name" Width="Auto" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Prices[Id]}" Header="Price" Width="Auto" />
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
我理解为什么“价格[Id]”不起作用('因为类似漫画中没有房产价格。但是我想从目前的背景中退一步,从主要价格中抢夺房产价格DataContext(MainWindow),然后通过ListView集合的当前迭代的Id属性查找价格。
我知道我可以把价格放在漫画课上,但这不是这个练习的重点。我知道在现实世界中我会需要访问这样的不同集合,并且我想知道如何做到这一点(或者如果真的有可能)。
我一直试图谷歌这没有运气,因为我还不知道正确的C#/ XAML术语来说明谷歌有用的问题。
答案 0 :(得分:1)
这是使用Converter
快速实施的实施方案。请注意,为了获得&#34;价格&#34;转换器中的字典,我使用MultiValueConverter,以便它也可以传递(以及Id)。
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525"
x:Name="MyWindow">
<Grid>
<Grid.Resources>
<wpfApplication1:IdToPriceConverter x:Key="IdToPriceConverter" />
</Grid.Resources>
<ListView ItemsSource="{Binding ExpensiveIssues}" x:Name="viewNumbers" HorizontalAlignment="Left" Margin="137,52,0,0" VerticalAlignment="Top">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Issue Name" Width="Auto" />
<GridViewColumn Header="Price" Width="Auto" >
<GridViewColumn.DisplayMemberBinding>
<MultiBinding Converter="{StaticResource IdToPriceConverter}">
<Binding Path="Id"/>
<Binding Path="DataContext.Prices" RelativeSource="{RelativeSource AncestorType=Window}"/>
</MultiBinding>
</GridViewColumn.DisplayMemberBinding>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
转换器:
namespace WpfApplication1
{
public class IdToPriceConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var id = values[0] is int ? (int) values[0] : -1;
var prices = values[1] as Dictionary<int, decimal>;
if (-1 != id)
{
if (null != prices)
{
return prices[id].ToString(CultureInfo.InvariantCulture);
}
}
return String.Empty;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
如果您有任何问题,请与我们联系。
答案 1 :(得分:0)
您可以将Price添加为漫画类型的属性,而不是单独的价格词典,即
public class Comic
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
您的linq查询也会相应更改:
public IEnumerable<Comic> ExpensiveIssues
{
get
{
var result = from issue in issues where issue.Price >= 10 select issue;
return result as IEnumerable<Comic>;
}
}
在XAML中,然后将第二个网格列绑定到Price属性
答案 2 :(得分:0)
这是我认为你在Lambda中的意思。
var result = issues.Where(x => Prices.Any(y => y.Key == x.Id && y.Value > 10));
这将返回IEnumerable<Comic>
,其中Comic.Id等于字典Key且值大于10
希望有所帮助