【发布时间】:2016-11-03 12:41:43
【问题描述】:
我想创建一个在后台执行操作并可以通过托盘图标控制的应用程序。这个托盘图标有一个带有复选框的上下文菜单,可以将其设置为启用,然后后台任务启动。
我正在使用 WPF 和 Hardcodet WPF NotifyIcon。
这是我的 MainWindow.xaml:
<Window x:Name="mainWindow" x:Class="MyTrayApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MyTrayApplication"
xmlns:tb="http://www.hardcodet.net/taskbar"
mc:Ignorable="d"
Title="MainWindow" Height="10" Width="10" Visibility="Hidden">
<tb:TaskbarIcon x:Name="taskbarIcon" IconSource="MyTrayApplication.ico" ToolTipText="My tray application" >
<tb:TaskbarIcon.ContextMenu>
<ContextMenu>
<MenuItem x:Name="enabledItem" Header="Enabled" IsCheckable="True" IsChecked="{Binding Path=Enabled, ElementName=mainWindow, UpdateSourceTrigger=PropertyChanged}"/>
<MenuItem x:Name="configureItem" Header="Configure..." Click="configureItem_Click"/>
<MenuItem x:Name="exitItem" Header="Exit" Click="exitItem_Click"/>
</ContextMenu>
</tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>
</Window>
这是我的代码:
using System;
using System.Windows;
namespace MyTrayApplication {
/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
private bool _enabled;
public MainWindow() {
InitializeComponent();
}
private void exitItem_Click(object sender, RoutedEventArgs e) {
Close();
}
private void configureItem_Click(object sender, RoutedEventArgs e) {
// Code to fire up configuration
}
public bool Enabled {
get {
return _enabled;
}
set {
_enabled = value;
Console.WriteLine(value);
// Code to enable the background task
}
}
}
}
这不起作用。运行时我在输出中得到以下内容:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=mainWindow'. BindingExpression:Path=Enabled; DataItem=null; target element is 'MenuItem' (Name='enabledItem'); target property is 'IsChecked' (type 'Boolean')
奇怪的是:当我为 IsChecked 绑定键入 ElementName= 时,在 XAML 编辑器中找到了 mainWindow IS,正如 IntelliSense 向我显示的那样。
做的工作是在InitializeComponent(); 之后以编程方式在代码隐藏中设置DataContext:
DataContext = this;
然后将绑定更改为:
IsChecked="{Binding Enabled, UpdateSourceTrigger=PropertyChanged}"
这会输出以下内容:
System.Windows.Data Error: 40 : BindingExpression path error: 'Enabled' property not found on 'object' ''TaskbarIcon' (Name='taskbarIcon')'. BindingExpression:Path=Enabled; DataItem='TaskbarIcon' (Name='taskbarIcon'); target element is 'MenuItem' (Name='enabledItem'); target property is 'IsChecked' (type 'Boolean')
但它有效。
我在这里做错了什么?还是以编程方式设置DataContext?
【问题讨论】:
-
也许您必须将其更改为“IsEnabled”属性。
-
不,我想绑定 IsChecked,但我想通了。我必须在开头的
<Window>标记中设置DataContext="{Binding RelativeSource={RelativeSource Self}}"并使用第二个更短的绑定。 -
抱歉没有很好地阅读您的问题。我误会了。
-
看起来,在第二次尝试中,“enabledItem”的 DataContext 在第一时间设置为 TaskbarIcon 而不是主窗口
-
是的,就是这样。奇怪的是,
FindAncestor方法也不起作用,但我在其他评论中提到的方法有效。
标签: c# wpf xaml data-binding