2014-04-01 80 views
0

假設您有一個項目列表,每個項目都有一個Id和一個Name屬性。然後你有一個字典(一個單獨的屬性),將ID映射到價格。C#xaml綁定到別處的屬性

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術語來提出谷歌問題propery是有用的。

+1

你看過轉換器嗎?如果需要,我可以提供一個例子。 –

+0

不,我還沒有讀過它們。這是做這種事的標準機制嗎? – Creature

+0

好吧,我試着使用一個轉換器,但我不知道如何獲得轉換器類的價格屬性。 Prices屬性是MainWindow類的一個實例屬性。如何從IdToPriceConverter獲取MainWindow類的當前實例? '公共類IdToPriceConverter:的IValueConverter { 公共對象轉換(對象的值,類型TARGETTYPE,對象參數,字符串語言) { 返回價格[值作爲INT]; } //結束轉換 }' 如果你有一個例子,這將是超級有用!謝謝。 – Creature

回答

1

下面是一個使用Converter快速工作的實施,這將返回一個IEnumerable<Comic>。請注意,爲了獲得轉換器中的「價格」字典,我使用了一個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(); 
     } 
    } 
} 

讓我知道如果您有任何問題。

+0

工作!非常感謝! – Creature

0

您可以添加的價格爲您的漫畫式的而不是價格的一個單獨的字典的屬性,即

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屬性

+0

謝謝,我知道我可以把價格在漫畫類本身,但這不是這項工作的地步。我知道,我將在現實世界中的實例,我需要訪問不同的集合這樣的,我想知道如何做到這一點(或者,如果它真的可能)。 – Creature

0

繼承人我認爲你的意思是在Lambda中。

var result = issues.Where(x => Prices.Any(y => y.Key == x.Id && y.Value > 10)); 

其中Comic.Id等於詞典鍵和值大於10

希望它可以幫助

+0

LINQ查詢我已經在那裏工作,這是鍛鍊的不同部分。我的問題是關於顯示結果。我會去編輯查詢了我的問題,以便它不會混淆問題。對於那個很抱歉。 – Creature