如何在 WPF 中按名称查找样式触发器嵌入元素?

2024-04-18

首先,问题的核心:如果通过样式触发器将一个元素指定为 ContentControl 的内容,我似乎无法按名称找到它。

现在,了解更多详细信息:我有一个面板,其布局和功能根据其数据上下文而有很大差异,这是来自错误库的错误。当该错误为空时,它是一个搜索表单,当它非空时,它是该错误属性的简单查看器。 XAML 看起来像:

<ContentControl DataContext="...">
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Setter Property="Content">
                <Setter.Value>
                    ...
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <DataTrigger Binding="{Binding}" Value="{x:Null}">
                    <Setter Property="Content">
                        <StackPanel>
                            <TextBox Name="Waldo"/>
                            <Button .../>
                        </StackPanel>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

当用户单击文本框旁边的按钮时,我会在后面的代码中收到回调。从那时起,我希望能够访问文本框的各种属性。问题是,在哪里Waldo? :)

在后面的代码中,我尝试了以下几种变体,但都收效甚微:

this.FindName("Waldo"); // Always returns null

我已经看到很多关于这个主题的讨论,因为它涉及模板 https://stackoverflow.com/questions/820201/how-to-access-a-wpf-control-located-in-a-controltemplate但不是因为它涉及直接使用触发器设置内容。也许是因为我这样做违反了各种最佳实践:)

谢谢你!


如果一个元素被指定为Content of a ContentControl通过样式触发器,我似乎无法按名称找到它。

如果您需要访问Content在触发发生之前,这很可能是不可能的。在这种情况下,主要是在DataTrigger发生之后获取访问权限。

我这样做违反了各种最佳实践

也许这不是在 WPF 中使用 Сontrol 的正确方法,您仍然需要访问更多内容dynamic内容,以后可以更改。但无论如何,有两种方法可以使用 Сontrol - 就像现在和 MVVM 风格。 MVVM 风格最适合具有不同业务逻辑的大型且不太复杂的应用程序。如果您的情况是为了方便应用,在这种情况下,我认为这没有什么问题。除了做一个MVVM风格的项目需要从头开始之外,将常规方法和正确方法结合起来并不是一个好方法。

我创建了一个小示例来演示给定情况的访问控制。有一个属性对应Content的类型,默认是Init。如果你分配null对于此属性,将加载动态内容。

这就是我访问的方式TextBox:

private void GetAccessToTextBox_Click(object sender, RoutedEventArgs e)
{
    TextBox MyTextBox = null;
    StackPanel panel = MainContentControl.Content as StackPanel;

    foreach (object child in panel.Children)
    {
        if (child is TextBox)
        {
            MyTextBox = child as TextBox;
        }
    }

    if (MyTextBox != null) 
    {
        MyTextBox.Background = Brushes.Gainsboro;
        MyTextBox.Height = 100;
        MyTextBox.Text = "Got access to me!";
    }
}

下面是一个完整的示例:

XAML

<Window x:Class="AccessToElementInContentControl.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:this="clr-namespace:AccessToElementInContentControl"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <this:TestData />
    </Window.DataContext>

    <Window.Resources>
        <Style TargetType="{x:Type ContentControl}">
            <Setter Property="Content">
                <Setter.Value>
                    <Label Content="InitContent"
                           HorizontalAlignment="Center"
                           VerticalAlignment="Center" />
                </Setter.Value>
            </Setter>

            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=TypeContent}" Value="{x:Null}">
                    <Setter Property="Content">
                        <Setter.Value>
                            <StackPanel Name="NullStackPanel">
                                <TextBox Name="Waldo" Text="DynamicText" />
                                <Button Width="100" Height="30" Content="DynamicButton" />
                            </StackPanel>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>

    <Grid>
        <ContentControl Name="MainContentControl" />

        <Button Name="SetContentType"
                Width="100"
                Height="30" 
                HorizontalAlignment="Left"
                Content="SetContentType"
                Click="SetContentType_Click" />

        <Button Name="GetAccessToButton"
                Width="110"
                Height="30" 
                HorizontalAlignment="Right"
                Content="GetAccessToTextBox"
                Click="GetAccessToTextBox_Click" />
    </Grid>
</Window>

Code-behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void SetContentType_Click(object sender, RoutedEventArgs e)
    {
        TestData test = this.DataContext as TestData;

        test.TypeContent = null;
    }

    private void GetAccessToTextBox_Click(object sender, RoutedEventArgs e)
    {
        TextBox MyTextBox = null;
        StackPanel panel = MainContentControl.Content as StackPanel;

        foreach (object child in panel.Children)
        {
           if (child is TextBox)
           {
                MyTextBox = child as TextBox;
           }
        }

        if (MyTextBox != null) 
        {
            MyTextBox.Background = Brushes.Gainsboro;
            MyTextBox.Height = 100;
            MyTextBox.Text = "Got access to me!";
        }
    }
}

public class TestData : NotificationObject
{
    private string _typeContent = "Init";

    public string TypeContent
    {
        get
        {
            return _typeContent;
        }

        set
        {
            _typeContent = value;
            NotifyPropertyChanged("TypeContent");   
        }
    }
}

public class NotificationObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 WPF 中按名称查找样式触发器嵌入元素? 的相关文章

  • 在单个 C# 泛型方法中返回可为 null 和 null?

    C 泛型方法是否可以返回对象类型或 Nullable 类型 例如 如果我有一个安全的索引访问器List我想返回一个值 稍后我可以使用以下任一方法检查该值 null or HasValue 目前我有以下两种方法 static T SafeGe
  • C++11 中具有 C 链接的复杂类型

    我需要将 C 库的标头包含到我的 C 11 代码中 现在 标头提供了涉及大量的例程和数据结构double complex到处都是 例如 include
  • 如何从 webmethod 向 AJAX 调用返回异常?

    我回来了List
  • 确保 unsigned int/long 始终在 C# 中的检查上下文中执行

    有没有人觉得奇怪 uint 和 ulong 的默认上下文是未检查的 而不是检查的 因为它们旨在表示永远不能为负的值 因此 如果某些代码试图违反该约束 在我看来 自然且首选的行为是抛出异常 而不是返回最大值 这很容易使重要数据处于无效状态并且
  • .NET:EventHandler 竞争条件修复如何工作?

    以下模式用于在引发事件时避免竞争条件 以防另一个线程取消订阅 MyEvent 使其为空 class MyClass public event EventHandler MyEvent public void F EventHandler h
  • 如何有效地左填充字节数组

    假设我有一个数组 LogoDataBy byte 0x00000008 0x00000000 0x41 0x00000001 0x42 0x00000002 0x43 0x00000003 0x44 0x00000004 0x31 0x00
  • 如何修复 TcpClient Ip 标头错误校验和

    我正在使用 System Net Sockets TcpClient 类 但每当我通过网络发送自定义数据包时 我都会在wireshark捕获上看到错误的校验和 我该如何修复它 问题是您在网络接口上设置了校验和卸载 这会导致您的网卡计算校验和
  • 用于轻松动态反射的 C# 库

    是否有任何库 例如开源项目等 可以更轻松地使用复杂的反射 例如动态创建对象或类 检查实例等 Thanks 有一个LinFu http www codeproject com KB cs LinFuPart1 aspx可用的库除了反射之外还可
  • 等于方法实现助手 (C#)

    每次我编写一些数据类时 我通常都会花很多时间编写 IEquatable 实现 我写的最后一堂课是这样的 public class Polygon public Point Vertices get set 实施 IEquatable 是一项
  • Apple IOS 上的 C# 应用程序 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有基于 C Net 的应用程序 有什么方法可以在 Apple IOS 上运行这些应用程序吗 我没有资
  • 使用 c# 中的 c++ ref 中的引用从 C# 调用 C++ 代码错误

    所以在我的 c dll 文件中我得到了以下函数 DLL void GetUserPass char userName char passWord userName ceva passWord altceva 现在我想从 c 调用它 但它给了
  • 为什么C++中没有“NULL引用”?

    我正在阅读 C 常见问题解答 8 6 什么时候应该使用引用 什么时候应该使用指针 http www parashift com c faq lite refs vs ptrs html 特别是以下声明 可以时使用引用 必要时使用指针 上述情
  • 如何使用 HttpClient 验证 Pardot API

    我花了大约一天的时间尝试对 Pardot API 进行身份验证 它不喜欢我尝试发布消息正文的方式 所以我想发布对我有用的解决方案 如果您有任何建议或替代方案 我想听听 ServicePointManager SecurityProtocol
  • 获取RFC返回的嵌套结构的值?

    我是 C 新手 我有 rfc 它以嵌套结构的形式从 SAP 系统返回数据 但是当我使用以下方式获取该数据时 IrfcTable table rfc getTable exporting parameter et customer 它仅返回第
  • C# 的 user32 和内核方法列表 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有没有一个很好的清单来说明我们可以从中进口什么user32 dll and kernel dll并在 C 中使用 我是 Windows A
  • 如何获取数字列的确切类型,包括。规模和精度?

    有没有办法知道列中列的确切类型DataTable 现在我正在这样做 DataTable st dataReader GetSchemaTable foreach DataColumn col in st Columns var type c
  • 比较 C# 中的对象属性[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动
  • 如何从 WPF 应用程序访问 Windows 文件预览图标

    我在一个目录中有一堆图片和视频 需要在WPF应用程序中显示 我正在考虑将Win7大图标本身显示为预览图像 因为这将节省我从视频文件中抓取适当帧的工作 因为 Windows 已经很好地完成了这项工作 有任何代码片段可以访问此 Shell 图标
  • 我可以创建一个 List> 吗?

    我正在尝试创建一个列表WeakReference使用 4 5 泛型实现 这样我就可以避免类型检查和转换WeakReference目标 但 WeakReference
  • Eclipse CDT C/C++:包含另一个项目的头文件

    我在 Eclipse CDT 中有两个 C 项目main and shared In shared我有一个名为calc h 我想在中使用这个标头main 所以我做了以下事情 added include calc h到相关文件main In

随机推荐