2014-12-02 44 views
2

我已經將ItemsFlyout添加到ItemsControl.ItemTemplate中的按鈕。此外,我能夠將當前項目綁定爲CommandParameter。 現在我想將Command綁定到MenuFlyoutItem。 在代碼隱藏:如何從資源中使用ElementName綁定?

LayoutRoot.DataContext = this; 

所以,如果我綁定到LayoutRoot我實際上將綁定到我目前的用戶控件。但以下綁定不起作用:

Command="{Binding ActivateProfileCommand, ElementName=LayoutRoot}" 

它給了我沒有輸出錯誤,但它不工作。 下面是完整的例子:

<controls:HeaderDecorator x:Uid="AccountsHeader" Text="Accounts" x:Name="LayoutRoot" Name="LayoutRoot"> 
    <controls:HeaderDecorator.Resources> 
     <MenuFlyout x:Key="AccountMenuFlyout"> 
      <MenuFlyoutItem Text="Activate" Name="Activate" 
         Command="{Binding ActivateProfileCommand, ElementName=LayoutRoot}" 
         CommandParameter="{Binding}" /> 
     </MenuFlyout> 
    </controls:HeaderDecorator.Resources> 
    <StackPanel Orientation="Vertical"> 
     <ItemsControl ItemsSource="{Binding Settings.Profiles}" > 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <HyperlinkButton Content="{Binding}" FlyoutBase.AttachedFlyout="{StaticResource AccountMenuFlyout}" > 
         <i:Interaction.Behaviors> 
          <ic:ShowFlyoutBehavior /> 
         </i:Interaction.Behaviors> 
        </HyperlinkButton> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </StackPanel> 
</controls:HeaderDecorator> 

看來問題是我想要使用共享對象的資源。我可以做嗎?那麼爲何不?

+0

你在哪裏定義了ActivateProfileCommand? – Dani 2014-12-03 09:00:14

+0

ActivateProfileCommand在UserControl中。將LayoutRoot的DataContext設置爲此UserControl。其實我看到它應該是「{綁定DataContext.ActivateProfileCommand ...」,但這也不起作用。 – norekhov 2014-12-03 12:39:24

+0

嘗試將ElementName更改爲存儲該命令的UserControl。 – Dani 2014-12-03 13:53:26

回答

2

你看到這裏的問題是MenuFlyoutItem的datacontext不再是你也許認爲它是。我會盡我所能解釋這一點,因爲我知道與xaml一起工作的人已經遇到了這個問題,並且爲了這個問題在牆上打了幾天頭。也知道不要在你的特定場景中顯示錯誤;進一步增加了混亂。

簡而言之,當MenuFlyout被添加到集合中每個項目的ItemTemplate中時,它無法訪問您可能認爲它具有的數據上下文。在這種情況下,控件現在駐留的數據上下文實際上是它所坐的集合中的單個項目。

然而,這有一個解決方案。我有類似於你自己的東西。一個ItemsControl的它有它的ItemsTemplate定義包括的UIElement誰的FlyoutBase AP引用MenuFlyout在資源字典定義。

xaml幾乎相同,除了我不需要在綁定中使用元素名稱

但是,我現在已將注意力轉向集合所持有的類型。我有看起來像這樣的代碼。

public class AnItemToList 
{ 
    public AnItemToList(Action commandDel) 
    { 
     TestCommand = new RelayCommand(commandDel); 
    } 
    public string Name { get; set; } 
    public RelayCommand TestCommand { get; set; } 
} 

注意,命令在項目本身被定義,而我正經過該命令將通過構造執行的方法。

所有我對命令的MenuFlyoutItem結合做的是

<MenuFlyoutItem Text="Activate" 
       Name="Activate" 
       Command="{Binding TestCommand}"/> 

我沒有命令的參數組在這裏,我只是很快組建了一個基本的模板的Windows Phone應用程序和預先打包的ICommand實現沒有設置參數的委託。

如果您現在在命令調用的方法中插入一個斷點,您將看到它將從任何的MenuFlyoutItem的綁定到引用該命令的命令中調用。

請記住,這不是解決此問題的唯一方法;但這是我偶爾使用自己的一個。例如,在WPF XAML中,您可以使用RelativeSource去查找父控件的數據上下文上的命令。

希望這會有所幫助。

+0

是的,你是對的。唯一的問題是(通常我認爲)人會想要一個集合對象內的命令。不在「項目」本身內。導致如何在不知道收集的情況下刪除項目?我用另一種方法來解決這個問題。我創建了一個名爲「Pair」的樣本依賴項對象。在這個「Pair」中,我將Item和Object與命令放在一起。現在我可以在MenuFlyout資源中輕鬆地綁定Command和CommandParameter,並且它可以是完全不同的對象。 – norekhov 2014-12-12 09:42:30

0

這裏有一個一般的 「配對」 的對象:

public class Pair : DependencyObject 
{ 
    public static readonly DependencyProperty FirstProperty = DependencyProperty.Register("First", 
     typeof(object), typeof(Pair), new PropertyMetadata(null)); 

    public static readonly DependencyProperty SecondProperty = DependencyProperty.Register("Second", 
     typeof(object), typeof(Pair), new PropertyMetadata(null)); 

    public object First 
    { 
     get { return GetValue(FirstProperty); } 
     set { SetValue(FirstProperty, value); } 
    } 

    public object Second 
    { 
     get { return GetValue(SecondProperty); } 
     set { SetValue(SecondProperty, value); } 
    } 
} 

在ItemTemplate中,我把這樣的事情:

   <DataTemplate> 
        <Grid> 
         <Grid.Resources> 
          <viewModel:Pair x:Key="Tuple" First="{Binding DataContext, ElementName=LayoutRoot}" 
                  Second="{Binding}" /> 
         </Grid.Resources> 
         <HyperlinkButton Content="{Binding Second.ProfileName}" 
            DataContext="{StaticResource Tuple}" 
            FlyoutBase.AttachedFlyout="{StaticResource AccountMenuFlyout}" 
         </HyperlinkButton> 
        </Grid> 
       </DataTemplate> 

現在,我可以很容易地從我的資源參考元組元素是這樣的:

  <MenuFlyoutItem Text="Activate" Name="Activate" 
         Command="{Binding First.ActivateProfileCommand}" 
         CommandParameter="{Binding Second}" /> 
+0

我敢肯定地說,是的,最好在某些視圖模型中包含這些命令。關於訪問收藏的問題。這是我將該方法傳遞給該項目的原因,而不是在項目類本身中包含該方法。這種方法可以訪問該集合。何時刪除gc確實發生沒有問題。 我很高興你解決了你的問題。 – 2014-12-12 11:35:40