2009-03-03 21 views
1

在我爲我的教會設計的WPF頁面中,我有兩個綁定到兩個Linq-to-Entities查詢結果的ListBox控件:第一個listbox/query包含所有誰還沒有保證今年,第二個列表框/查詢包含所有已經承諾的人(以及他們相關的承諾)。具體做法是:引用WPF DataTemplate中的控件

var familiesWithNoPledges = from family in entities.Family.Include("Pledge") 
    where !family.Pledge.Where(p => p.PledgeYearID == pledgeYear).Any() 
    select family; 

var familiesWithPledges = from family in entities.Family 
    join pledge in entities.Pledge.Include("PledgeFrequency").Where(p => p.PledgeYearID == pledgeYear) on family equals pledge.Family 
    select new { family, pledge }; 

當應用程序的用戶從第一個列表框選擇一個家庭,ListBox中的項目稍微膨脹,以示對質押的領域,所以它很容易質押詳細信息添加到第二個列表框。它看起來是這樣的:

http://wouldbetheologian.com/images/PledgeManager.jpg (Offsite Image)

的基礎數據庫(除其他事項外),有一個「家庭」表1:許多關係到一個「承諾」表。當用戶點擊「Add Pledge」按鈕時,我想創建新的Pledge實例,將其保存到數據庫,然後刷新這兩個控件。

但我無法弄清楚如何做到這一點。如果我嘗試在代碼隱藏中做到這一點,它看起來並不像「Add Pledge」按鈕的(n-instance)事件處理程序可以引用有問題的控件;並在XAML中,如果我嘗試將ListBoxItem DataTemplate控件綁定到Family.Pledge(或Family.Pledge.FirstOrDefault())字段,那麼當我查看Add的事件處理程序中的當前Family對象時,這些字段仍爲空祈願按鈕。

有關如何解決這個問題的想法?還是有更好的UI模型,我應該看看?

在此先感謝。

回答

2

謝謝,安德魯,做到了。關鍵是我必須爲DockPanel創建一個單獨的DataContext,然後將它綁定到在模板中創建的Pledge對象的新實例。

<ListBox> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Grid> 
       <Grid.Resources> 
        <local:Pledge x:Key="pledge" /> 
       </Grid.Resources> 

       <DockPanel DataContext="{Binding Source={StaticResource pledge}}" > 
        <TextBox Name="txtAmount" Text="{Binding Path=Amount}" /> 
        <TextBox Name="txtEnvelopeID" Text="{Binding Path=EnvelopeID}" /> 
        <!-- Bind the Tag property of the Button to the DataContext of the ListBoxItem, i.e. the current Family object --> 
        <Button Tag="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}" Name="addPledge" Click="addPledge_Click" > 
         Add Pledge --> 
        </Button> 
       </DockPanel> 
      </Grid> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

我仍然需要對質押的對象適當地瞭解更多的細節設置,但我可以通過按鈕的Tag屬性綁定到它的模板父DataContext的,讓他們:

<Button 
    Tag="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}" 
    Name="addPledge" 
    Click="addPledge_Click" 
/> 

而且從那裏,我能夠處理其餘部分在後臺代碼:

private void addPledge_Click(object sender, RoutedEventArgs e) 
    { 
     try 
     { 
      // Set any additional necessary properties. 
      Button button = (Button)sender; 
      Pledge pledge = (Pledge)button.DataContext; 
      pledge.PledgeYear = (PledgeYear)cboYear.SelectedItem; 
      pledge.Family = (Family)button.Tag; 

      // Update the database and refresh the Listboxes. 
      entities.AddToPledge(pledge); 
      entities.SaveChanges(); 
      LoadUnpledgedListBox(); 
      LoadPledgedListBox(); 
     } 
     catch (System.Data.UpdateException ex) 
     { 
      MessageBox.Show("Error updating database: " + ex.Message); 
     } 
     catch (System.Exception ex) 
     { 
      Classes.Utils.HandleGenericError(ex); 
     } 
    } 

非常感謝 - 這我指出了正確的方向。

2

最簡單的方法是讓表示ListBox ItemsSource中的項目的類具有您在DataTemplate中引用的所有字段。然後在您的按鈕處理程序中,您可以使用按鈕的數據上下文訪問新的祈願信息。

private void AddPledge_Click(object sender, RoutedEventArgs e) 
    { 
     Button b = sender as Button; 
     PotentialPledge p = b.DataContext as PotentialPledge; 

     //do stuff with pledge 
    } 

可能有辦法做到這一點,而無需在模板領域是拼成的ItemsSource爲ListBox類(只是學習WPF我自己)的一部分,但這個工程。如果這沒有幫助,我會回頭看看(現在開始工作)。

無論如何,爲你的教會做一個應用程序真棒,它看起來很不錯。

相關問題