2016-01-28 100 views
1

在我的WPF應用程序中,我有Student和StudentDB類。WPF - 應用IValueConverter進行收集綁定

class StudentDB 
{ 
    int StudentId{get;set;} 
    string Name{get;set;} 
    string City{get;set;} 
    DateTimeOffset BirthDate{get;set;} 
} 

class Student 
{ 
    int StudentId{get;set;} 
    string Name{get;set;} 
    string City{get;set;} 
    DateTime BirthDate{get;set;} 
} 

兩個類之間的主要區別是生日屬性的數據類型。一個是DateTime,另一個是DateTimeOffset

在我的應用程序中有以下代碼。

IEnumerable<StudentDB> StudentDbs = GetAllStudentFromDB(); 
IEnumerable<Student> Students = new IEnumerable<Student> Students(); 

XAML:

<DataGrid ItemsSource="{Binding Students, Mode=TwoWay}" AutoGenerateColumns="True"> 

我需要在DataGrid中顯示學生的名單。 我無法綁定StudentDbs,因爲它具有DateTimeOffset類型屬性。

爲了解決上述問題,我需要應用Value Converter,它會將StudentDb對象轉換爲Student對象。

我知道如何實現IValueConverter接口I.但我不知道如何將它應用於集合。

任何人都可以建議我一個解決方案來解決這個問題嗎?

+1

也許你可以嘗試類似於[這個答案](http://stackoverflow.com/a/7635319/752842) – Dzyann

回答

0

你不需要價值轉換器。

更好的方式是通過LINQ或在視圖模型的其他方式StudentDB轉換爲Student,然後綁定Student對象的集合到你DataGrid

IEnumerable<StudentDB> StudentDbs = GetAllStudentFromDB(); 
IEnumerable<Student> Students = new StudentDbs.Select(student => ConvertToDto(student)); 

private Student ConvertToDto(StudentDB) 
{ 
    return new Student 
    { 
     StudentId = StudentId, 
     Name = Name, 
     City = City, 
     BirthDate = BirthDate.DateTime 
    }; 
} 

<DataGrid ItemsSource="{Binding Students, Mode=TwoWay}" AutoGenerateColumns="True"> 

而且最好是使用ObservableCollection<T>以防止內存泄漏,並允許收集的變化。

+0

@Hi Vadim,實際上我使用DataServiceCollection (Odata Service)來獲取學生列表從數據庫。那麼如何將更改後的數據(在datagrid中)以MVVM方式保存回數據庫? – Rahul

+0

@Rahul它取決於許多因素,例如1.您使用的是什麼ORM。 2.你有2層或3層的應用程序嗎? 3.你添加/刪除項目或只是改變已經存在的項目。 此外,它是基於主要意見。通常我使用ViewModel層,服務層和數據訪問層。服務層包含業務邏輯,則它可以使用UpdateService的StudentService(IEnumeralbe students)方法。業務邏輯會將DTO與實體進行比較,並使用存儲庫方法保存更改。 –

+0

我正在使用EF及其3層應用程序。我需要執行crud操作。 – Rahul

1

回答您的主要要求:DateTimeOffset類具有名爲DateTime的屬性,它表示當前System.DateTimeOffset對象的日期和時間。因此,您仍然可以將StudentDbs綁定爲DataGrid的Itemsource,並且您可以直接綁定DataGrid中要實現您的需求的任何位置的屬性。

0

價值轉換器musst應用在列上。所以設置的AutoGenerateColumns =「假」,並手動添加列:

<DataGrid.Columns> 
<DataGridTextColumn Header="{lex:Loc ...}" 
Binding="{Binding StarString, Converter={StaticResource ...}}"> 

當AutoGenerating是真實的,使用DataGrid的AutoGeneratingColumn事件。在XAML中添加:

<DataGrid ItemsSource="{Binding Students, Mode=TwoWay}" AutoGenerateColumns="True" AutoGeneratingColumn="StartListGrid_OnAutoGeneratingColumn" 

後面的代碼中添加類似:

private void StartListGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
    { 
     if (e.PropertyName == "BirthDate" && e.Column is DataGridTextColumn) 
     { 
      var textColumn = e.Column as DataGridTextColumn; 
      textColumn.Binding = new Binding(e.PropertyName) 
      { 
       Converter = new MyValueConverter(); 
      }; 
     } 
    } 

請注意,要覆蓋約束力。

+0

我需要自動生成列。任何解決方案 – Rahul

+0

網格在創建列時引發事件。您可以使用此事件在後面的代碼中手動生成綁定。檢查這篇文章:https://msdn.microsoft.com/en-us/library/cc903950(v=vs.95).aspx – unkreativ

+0

好吧,那麼你如何應用價值轉換器? – Rahul