WPF NotifyIcon中ItemsControl中按钮的命令绑定

时间:2016-09-23 02:11:35

标签: c# wpf binding itemssource notifyicon

我在我的应用程序中使用hardcodet的WPF NotifyIcon,这是使用MVVM Light实现的。我正在尝试为图标创建自定义TrayPopup。在这个弹出窗口中,我有一个ItemsControl,其ItemsSource是我的ViewModel中的对象列表“NumberList”。对于我的DataTemplate,我使用的网格显示了我的源对象的名为“Id”的属性,以及一个按钮。按钮我试图绑定到我的ViewModel中的RelayCommand。我在过去使用RelativeSource来使用ItemsControls做了类似的事情来获取Window Ancestor的DataContext。我这次尝试了类似的方法,但是当我运行应用程序时,打开TrayPopup,然后单击按钮没有任何反应。我的命令不会在我的ViewModel中触发。

作为测试,我尝试在我的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>

我相信ViewModel中的所有内容都是正确的,因为我之前使用的是此应用程序的先前版本。到目前为止,除了NotifyIcon之外,我还没有遇到任何问题。有什么想法吗?

1 个答案:

答案 0 :(得分: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>