2010-01-23 57 views
2

我有ListBoxDataTemplate。該模板上有一個Button。當點擊Button時,我想用每行的對象(在這種情況下稱爲WorkItemTypeMappings)執行一些邏輯。從DataTemplate上的按鈕獲取列表框行對象

OnClick我該如何從Buttonobject sender)到該按鈕所在行的對象?

這裏是我的ListBox的XAML:

<ListBox ItemsSource="{Binding Source={StaticResource WorkItemTypeMappingsCollectionView}}" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Name="lstWITypes"> 
    <ListBox.GroupStyle> 
     <x:Static Member="GroupStyle.Default"/> 
    </ListBox.GroupStyle> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Grid HorizontalAlignment="Stretch"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="2*"/> 
        <ColumnDefinition Width="2*"/> 
        <ColumnDefinition Width="50"/> 
       </Grid.ColumnDefinitions> 
       <TextBlock Grid.Column="0" Text="{Binding SourceType, Converter={StaticResource WorkItemTypeToStringConverter}}"/> 
       <ComboBox Grid.Column="1" SelectedItem="{Binding DestType}" ItemsSource="{Binding WorkItemTypesForCurrentDestProject, Source={x:Static loc:MainMediator.Instance}, diagnostics:PresentationTraceSources.TraceLevel=High}" DisplayMemberPath="Name" /> 

       <!-- This is the button--> 
       <Button Grid.Column="2" Content="{Binding PercentMapped}" 
         Click="ManualMappingClick"/> 
      </Grid> 
     </DataTemplate>           
    </ListBox.ItemTemplate> 
</ListBox> 

回答

2

你可以做的替代方法是使用命令而不是事件。如果你將你的按鈕綁定到一個命令並傳遞一個命令參數,你應該能夠獲得與該按鈕相關的項目。示例代碼:

<!-- This is the button--> 
<Button 
    Grid.Column="2" 
    Content="{Binding PercentMapped}" 
    Command="SolutionNamespace:CommandClass.ButtonClickedCommand" 
    CommandParameter="{Binding}" /> 

我不知道你是多麼熟悉WPF指揮,但你會發現,CommandParameter結合上下文沒有路徑名,也就是說它綁定到你需要的WorkItemTypeMappings。

命令示例代碼:

public static SimpleCommand ButtonClickedCommand { get; set; } 

static CommandClass() 
{ 
    ButtonClickedCommand = new SimpleCommand 
          { 
           ExecuteDelegate = 
           x=> ButtonClicked(x as WorkItemTypeMappings) 
          }; 
} 


public static ButtonClicked(WorkItemTypeMappings mappings) 
{ 
    if(mappings != null) MessageBox.Show(mapping.PercentMapped) 
} 

你會發現ButtonClickedCommand是靜態的,因爲按鈕無法從當前綁定上下文訪問的命令,這是必需的。

SimpleCommand只是ICommand的一個簡化實現,如果你不確定,可以谷歌這一個。我希望這不是對你的問題矯枉過正,但你不能錯誤的WPF命令。

祝你好運。

+0

好東西在這裏。我一直想嘗試我的命令。這將是一個很好的嘗試。我會試試看,如果能解決問題,我會接受。 – Vaccano 2010-01-25 15:01:44

+0

這太棒了!我覺得我是這樣做的「正確的方式」。謝謝你的偉大答案。 – Vaccano 2010-01-25 23:10:48

+0

我很高興你讓它工作給我的最小代碼片段。不用客氣。 – 2010-01-27 05:15:22

0

你試過ListBox.SelectedItem?

+1

是的。但是,可以單擊按鈕而不選擇項目(我選中) – Vaccano 2010-01-24 06:48:56

1

嘗試使用VisualTreeHelper查找按鈕的父級ListBoxItem。幾個不錯的一般的通用輔助功能可以在這裏找到:

How can I find WPF controls by name or type?

因此,舉例來說,你可以找到Click事件ListBoxItem中,像這樣的電話:

ListBoxItem item = UIHelper.FindVisualParent<ListBoxItem>(sender); 
+0

我不需要ListBoxItem。我需要它背後的數據。 (正如我在我的問題中所說的:「每一行的對象(在這個對象中稱爲WorkItemTypeMappings)」 – Vaccano 2010-01-24 06:50:59

+0

ListBoxItem是「背後的數據」。一旦你有ListBoxItem,你應該能夠像這樣施放它: WorkItemTypeMappings dataObject = item as WorkItemTypeMappings; – sdcoder 2010-01-24 15:16:05

0

另外,如果你已經有了對ListBoxControl的引用,並且你也有表示該行的數據項(我假設你已經擁有該綁定,因此可以將它拖出按鈕上的DataContext),你可以詢問ItemsContainerGenerator. ContainerFromItem給你給你行的實際UIElement。

itemcontainergenerator可以作爲listview本身的屬性找到。 (從技術上說項目控制,因爲那是它定義的地方)

+0

我實際上正在尋找另一種方式。我需要表示該行的數據項。 – Vaccano 2010-01-24 06:49:53