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

时间:2014-02-24 01:15:18

标签: c# wpf xaml triggers contentcontrol

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

现在,更多细节:我有一个面板,它的布局和功能根据其数据上下文而有很大差异,这是一个bug存储库中的错误。当该bug为null时,它是一个搜索表单,当它为非null时,它是该bug的属性的简单查看器。然后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

我已经看到很多关于这个主题的讨论,因为它与templates有关,但不是因为它与直接用触发器设置内容有关。也许是因为我违反了各种各样的最佳实践:)

谢谢!

1 个答案:

答案 0 :(得分:1)

  

如果通过样式触发器将某个元素指定为Content的{​​{1}},我似乎无法按名称找到它。

如果您在触发发生之前需要访问ContentControl,则很可能无法访问。在这种情况下,DataTrigger发生后访问的主要内容。

  

我这样做违反了各种各样的最佳做法

也许这不是在WPF中使用Сontrol的正确方法,您仍然需要访问动态内容,这些内容以后可以更改。但无论如何,有两种方法可以使用Сontrol - 就像现在和MVVM风格一样。 MVVM样式最适合具有不同业务逻辑的大型和不太复杂的应用程序。如果在您的情况下易于应用,在这种情况下,我没有看到任何错误。除了做一个MVVM样式的项目需要从头开始,结合常规方法和正确的方法不是一个好方法。

我创建了一个小例子来演示给定情况的访问控制。有一个属性与内容类型相对应,默认值为Content。如果为此属性分配 null ,则会加载动态内容。

这就是我访问Init的方式:

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