2010-11-22 18 views
0

這是我能想到的最好的方式來說明我的問題,這裏是場景:我有一個ListView綁定到對象的集合。每個對象都有一個屬性UserID,它只是對象User的參考ID。在我的ListView我希望顯示對象和User的多個屬性。爲此,我創建了一個實現MultiValueConverter的類來充當用戶對象的查找表。因此,我使用多值綁定,通過值轉換器UserID和底層ViewModel公開的字典查找表。無論如何設置由ListView列共享的行'DataContext'?

這一切都工作正常和丹迪,除非我希望有一種方法,我可以設置DataContextListView列共享'行'的東西。通過這種方式,我可以將我的值轉換器更改爲僅返回User對象,而不是用戶對象的特定屬性。然後我可以綁定到DataContext的屬性。我不想爲我想要公開的每個用戶屬性創建一個新的值轉換器。我能想到的唯一方法就是將屬性名稱傳遞給值轉換器並使用反射。

任何想法?我意識到這個DataContext我夢寐以求的是數據對象的工作綁定到ListViewItemsSource,但也許還有一些我可以使用的東西。附加屬性似乎解決了我所有的WPF問題,所以我打賭這個解決方案需要使用AttachedProperty來創建這個'datacontext'

我確定有人會告訴我從數據對象中暴露User對象而不是使用一些使用用戶標識和查找表的倒退方法,但是,我這樣做是有原因的。謝謝。

<ListView.View> 
    <GridView> 
     <GridViewColumn> 
      <GridViewColumn.Header>User</GridViewColumn.Header> 
      <GridViewColumn.CellTemplate> 
       <DataTemplate> 
        <TextBlock MinWidth="120"> 
         <TextBlock.Text> 
          <MultiBinding Converter="{StaticResource UserIDConverter}"> 
           <Binding Path="UserID" /> 
           <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=UserControl}" Path="DataContext.Users"/> 
          </MultiBinding> 
         </TextBlock.Text> 
        </TextBlock> 
       </DataTemplate> 
      </GridViewColumn.CellTemplate> 
     </GridViewColumn> 
    </GridView> 
</ListView.View> 

轉換器:

public class UserIDConverter : IMultiValueConverter 
{ 
    #region IMultiValueConverter Members 

    public object Convert(object[] values, Type targetType, object parameter, 
          System.Globalization.CultureInfo culture) 
    { 
     int userId = (int)values[0]; 
     IDictionary<int, PhoneUser> table = values[1] as IDictionary<int, PhoneUser>; 
     if (table.ContainsKey(userId)) 
     { 
      PhoneUser user = table[userId]; 
      return user.LastName; 
      //I'd like to just return user !! 
     } 

     return null; 
    } 

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

    #endregion 
} 
+0

在這一點上,我認爲我的非UI層只是不適合構思,所以我只是要重新做它們,以便我可以在我的數據對象中使用User對象引用。 – 2010-11-24 18:06:42

回答

0

所以,如果我正確理解你,你希望你的轉換器只返回一個完整的PhoneUser對象,然後讓每一列決定哪一個屬性PhoneUser要抓取?

如果你真的要堅持這個複雜的方法,我認爲你的反思想法(將屬性名稱傳入轉換器並使用反射返回值)將是最好的。


這就是說,我無法拒絕給出你不想聽到的答案(即使它沒有幫助你,它可能會幫助別人)。這裏就是我想要真的建議你這樣做......

  1. 創建,結合當前的對象的類(說這就是所謂的Foo)和PhoneUser

    public class FooPhoneUser 
    { 
        Foo Foo { get; set; } 
        PhoneUser User { get; set; } 
    } 
    
  2. 使用LINQ到這兩個類結合在一起:

    var FooPhoneUsers = 
        from 
         f in Foos 
        join 
         pu in PhoneUsers on f.UserId equals pu.Id 
        select 
         new FooPhoneUser { Foo = f, User = pu }; 
    
  3. 從你GridViewColumn擺脫所有綁定標記,而只是把這樣的事情:

    <TextBlock MinWidth="120" Text={Binding User.LastName} /> 
    

    <TextBlock MinWidth="120" Text={Binding Foo.SomeOtherProp} /> 
    
0

這會容易得多,如果你能與PhoneUser填充,而不是僅僅的ID數據的對象,那麼你可以做:

<DataTemplate> 
    <StackPanel> 
    <TextBlock MinWidth="120" Text="{Binding Path="User.FirstName}"> 
    </TextBlock> 
    <TextBlock MinWidth="120" Text="{Binding Path="User.LastName}"> 
    </TextBlock> 
    </StackPanel> 
</DataTemplate> 

班級結構看起來像這樣:

public class myDataObject //The data object you already have. 
{ 
    public string value1; 
    public string value2; 
    public PhoneUser User; //currently you have "UserID" here. 
} 

public class PhoneUser 
{ 
    public string FirstName; 
    public string LastName; 
} 

如果它不適合你找回所有的用戶數據首先被加載的數據對象時,你可以使用一個「延遲加載」的策略,像這樣:

public class myDataObject //The data object you already have. 
{ 
    public string UserID; 
    public string value2; 
    private PhoneUser _User; 
    public PhoneUser User 
    { 
     get 
     { 
      if(_User==null) 
       _User = getUserFromDatabase(UserID); 
      return _User; 
     } 
    } 
} 

我相信你能做到這一點,沒有任何更改您的代碼的結構。

+0

謝謝,但正如問題中所述,我不想在數據對象類中使用對用戶對象實例的引用。感謝您嘗試 – 2010-11-22 19:16:44

+0

對不起 - 我錯過了。你能詳細說明你不想這樣做的原因嗎?如果我知道你的要求是基於什麼的話,我可能會更好地給你一個好的答案。我認爲必須有一個比你嘗試的更好的策略。 – 2010-11-22 22:52:10

+1

'更好的策略',我相信你的權利。我只是要重寫其他圖層,以便可以在我的數據對象中使用User對象。我想我只是陷入了試圖做這項工作而不是整個項目的想法。 – 2010-11-24 18:12:01