7

背景:我正在为(可能)将我的 WinForms 应用程序转换为 WPF 进行原型设计。

我制作了非常简单的树视图事件处理程序,其代码为:

var treeViewItem = (TreeViewItem)e.NewValue;
var treeViewItemTag = treeViewItem.Tag;
if (treeViewItemTag == "ViewForAMs")
{
    ObjectQuery<AccountManagerView> oq = entities.AccountManagerViews;
    var q =
        from c in oq
        select c;
    dataGrid1.ItemsSource = q.ToList();
}

XAML 是:

<Window x:Class="AccountingWpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <DockPanel>
        <TreeView Name="treeView1" ItemsSource="{Binding Folders}"
          SelectedItemChanged="treeView1_SelectedItemChanged">
            <TreeViewItem Header="Account Manager View" Tag="ViewForAMs"/>
        </TreeView>
        <DataGrid AutoGenerateColumns="True" Name="dataGrid1" />
    </DockPanel>
</Window>

当我运行它时,我完全期望看到我的数据网格被填充,但 == 比较在上面的第二行代码中失败了。

调试器显示:

问题:为什么没有编译或运行时错误?(同样的问题另一种方式:实际上是在比较什么以使 == 运算符输出 FALSE?)

在此处输入图像描述

4

7 回答 7

4

Tag先投到string。在默认实现中object==比较引用。由于该Tag属性是 type object,因此它使用and==之间的最低公共运算符,即实现。通过转换为,使用 on 的实现,这是一个值比较。objectstringobjectTagstringstring

于 2011-04-25T18:53:03.730 回答
4

Object.Equals(treeViewItemTag, "ViewForAMs")改为使用

于 2011-04-25T18:54:05.340 回答
2

如果查看 treeViewItemTag 的类型,您会看到类型是对象,而不是字符串。因此,当您使用 == 时,您是在比较两个对象的引用。在这种情况下,这将始终返回 false。如果您改用 Equals() 或强制转换为字符串,那么它应该可以工作。

于 2011-04-25T18:54:19.053 回答
1

使用 Equals() 比较字符串。

更新:或将两者都转换为字符串。来自 MSDN 的示例:

string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine((object)a == (object)b);

第一个比较返回 true,但第二个返回 false(因为它比较的是引用,而不是字符串)。

于 2011-04-25T18:51:02.197 回答
1

TreeViewItem 属性中的 Tag 是一个对象,而不是字符串。== 是比较对象引用。要比较字符串,您应该使用 ToString() 进行比较:

if (treeViewItemTag.ToString() == "ViewForAMs")

但是你必须确保包含一个字符串,否则比较也会失败。

于 2011-04-25T18:54:58.023 回答
0

“treeViewItem.Tag”是对对象的引用。默认情况下,在 C# 中,== 运算符检查引用是否相等,即两个对象在内存中是一个且相同的对象。String 具有重载的 '==' 运算符以检查值是否相等,即字符串是否包含相同的内容。不过,要使用它,您需要将“treeViewItem.Tag”转换为字符串。

于 2011-04-25T18:55:10.250 回答
0

我不熟悉 WPF,但在 Winforms 上下文中,我会说 Tag 是 Object 类型。
Object 上的相等运算符比较引用。

如果您(或其他读者)可能想知道为什么这在某些情况下仍然有效:
当您通过 StringBuilder 或非托管函数构建字符串时,您不会得到所谓的实习生字符串。这意味着,有一种方法可以让您在运行时拥有两个具有相同内容的不同字符串对象。
通常,字符串指的是同一个实例,除非它们是在运行时构建的,如上所述。您可以调用 String.Intern 来获取具有相同内容的字符串的实习生引用。对于相同的内容,它们必然是相同的实例。在某些情况下,了解这个微小的细节可能会带来很大的帮助或大开眼界。

于 2011-04-25T18:59:04.883 回答