2016-09-23 139 views
0

我在我的应用程序中使用硬编码的WPF NotifyIcon,它使用MVVM Light实现。我正在尝试为图标创建一个自定义TrayPopup。在这个弹出窗口中,我有一个ItemsControl,其ItemsSource是我的ViewModel中的对象“NumberList”的列表。对于我的DataTemplate,我使用了一个显示我的源对象的“Id”属性的网格和一个按钮。我试图绑定回ViewModel中的RelayCommand按钮。我在过去通过使用RelativeSource获取窗口祖先的DataContext的Binding完成了类似的事情。这次我尝试了类似的方法,但是当我运行该应用程序时,打开TrayPopup,然后单击按钮什么也没有发生。我的命令没有在我的ViewModel中被触发。WPF中的ItemsControl中的按钮的命令绑定NotifyIcon

作为一个测试,我尝试向我的TrayPopup中添加另一个按钮,并将其命令绑定到ViewModel中的同一个按钮。该绑定工作正常,所以它不是我所知道的命令。

就像我说过的,我几乎完全在过去使用这种技术,从来没有在NotifyIcon中使用过。我已经尝试在按钮绑定到我的窗口的名称中指定ElementName,这没有奏效。我也尝试将RelativeSource更改为父TaskbarIcon,也没有成功。

以下是对同样的问题NotifyIcon的一个示例实现:

<tb:TaskbarIcon PopupActivation="LeftOrRightClick"> 
     <tb:TaskbarIcon.TrayPopup> 
      <Grid Background="White"> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="200"/> 
        <RowDefinition Height="30"/> 
       </Grid.RowDefinitions> 
       <ScrollViewer Grid.Row="0"> 
        <ItemsControl ItemsSource="{Binding NumberList, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"> 
         <ItemsControl.ItemTemplate> 
          <DataTemplate> 
           <Grid> 
            <Grid.ColumnDefinitions> 
             <ColumnDefinition Width="200"/> 
             <ColumnDefinition/> 
            </Grid.ColumnDefinitions> 

            <Label Grid.Column="0" Content="{Binding Id, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/> 
            <Button Grid.Column="1" Content="Test" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.TestCommand}"/> <!--This binding doesn't work!--> 
           </Grid> 
          </DataTemplate> 
         </ItemsControl.ItemTemplate> 
         <ItemsControl.ItemsPanel> 
          <ItemsPanelTemplate> 
           <StackPanel/> 
          </ItemsPanelTemplate> 
         </ItemsControl.ItemsPanel> 
        </ItemsControl> 
       </ScrollViewer> 

       <Button Grid.Row="1" Content="Test2" Command="{Binding TestCommand}"/> <!--This works--> 
      </Grid> 
     </tb:TaskbarIcon.TrayPopup> 
    </tb:TaskbarIcon> 

我相当有信心,一切都在视图模型是正确的,因为我一直在使用这个应用程序,我写的先前版本不久以前。到目前为止,除了这个NotifyIcon之外,我还没有遇到任何问题。有任何想法吗?

回答

0

经过一段时间后,我发现了一个答案,我的问题。我的ItemsPanelTemplate中的StackPanel具有DataContext,其中包含我想要将我的按钮绑定到的命令,我的主ViewModel。通过指定StackPanel的名称,我可以将我的按钮的ElementName设置为它的名称,然后绑定起作用。不知道为什么这个方法可以用StackPanel而不是主窗口。

不管怎么说,这是更新后的代码,如果任何人都运行在这个同样的问题:

<tb:TaskbarIcon PopupActivation="LeftOrRightClick"> 
    <tb:TaskbarIcon.TrayPopup> 
     <Grid Background="White"> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="200"/> 
       <RowDefinition Height="30"/> 
      </Grid.RowDefinitions> 
      <ScrollViewer Grid.Row="0"> 
       <ItemsControl ItemsSource="{Binding NumberList, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"> 
        <ItemsControl.ItemTemplate> 
         <DataTemplate> 
          <Grid> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="200"/> 
            <ColumnDefinition/> 
           </Grid.ColumnDefinitions> 

           <Label Grid.Column="0" Content="{Binding Id, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/> 
           <Button Grid.Column="1" Content="Test" Command="{Binding ElementName=trayMainStack, Path=DataContext.TestCommand}"/> <!--Updated binding works!--> 
          </Grid> 
         </DataTemplate> 
        </ItemsControl.ItemTemplate> 
        <ItemsControl.ItemsPanel> 
         <ItemsPanelTemplate> 
          <StackPanel Name="trayMainStack"/> 
         </ItemsPanelTemplate> 
        </ItemsControl.ItemsPanel> 
       </ItemsControl> 
      </ScrollViewer> 

      <Button Grid.Row="1" Content="Test2" Command="{Binding TestCommand}"/> <!--This works--> 
     </Grid> 
    </tb:TaskbarIcon.TrayPopup> 
</tb:TaskbarIcon>