首先,问题的核心:如果通过样式触发器将元素指定为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有关,但不是因为它与直接用触发器设置内容有关。也许是因为我违反了各种各样的最佳实践:)
谢谢!
答案 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