通过 wpf 中的 DependencyProperty 发送 UIElements

发布于 2024-09-27 06:19:10 字数 1204 浏览 1 评论 0原文

我有一个带有 DependencyProperty 的用户控件,该控件采用 UIElement。到目前为止,一切都很好,问题是我找不到该元素的子元素。

我认为问题是我缺乏知识,有人能告诉我问题是什么以及可能的解决方案吗?

我制作了一个像这样的小型测试程序

Usercontrol codebehind:

public UIElement TestSendUiElement
{
   get { return (StackPanel)GetValue(TestSendUiElementProperty); }
   set { SetValue(TestSendUiElementProperty, value); }
}

public static readonly DependencyProperty TestSendUiElementProperty =
 DependencyProperty.Register("TestSendUiElement", typeof(StackPanel), typeof(Test), new FrameworkPropertyMetadata(TestSendUiElementPropertyChanged));

private static void TestSendUiElementPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
   Console.WriteLine(VisualTreeHelper.GetChildrenCount((UIElement)e.NewValue));
}

xaml 使用 usercontrol:

<my:Test >
 <my:Test.TestSendUiElement>
  <StackPanel Orientation="Horizontal" Margin="0,2">
   <TextBox Height="23" Width="50" Margin="0,0,5,0" />
   <TextBox Height="23" Width="125" />
  </StackPanel>
 </my:Test.TestSendUiElement>
</my:Test>

Output is 0 Children 。不应该是2吗?

I have a user control with a DependencyProperty that takes a UIElement. So far, so good, the problem is I cannot find the element's children.

I think the problem is my lack of knowledge, could anyone tell me what the problem is and a possible solution?

I have made a small test-program like this

Usercontrol codebehind:

public UIElement TestSendUiElement
{
   get { return (StackPanel)GetValue(TestSendUiElementProperty); }
   set { SetValue(TestSendUiElementProperty, value); }
}

public static readonly DependencyProperty TestSendUiElementProperty =
 DependencyProperty.Register("TestSendUiElement", typeof(StackPanel), typeof(Test), new FrameworkPropertyMetadata(TestSendUiElementPropertyChanged));

private static void TestSendUiElementPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
   Console.WriteLine(VisualTreeHelper.GetChildrenCount((UIElement)e.NewValue));
}

xaml using the usercontrol:

<my:Test >
 <my:Test.TestSendUiElement>
  <StackPanel Orientation="Horizontal" Margin="0,2">
   <TextBox Height="23" Width="50" Margin="0,0,5,0" />
   <TextBox Height="23" Width="125" />
  </StackPanel>
 </my:Test.TestSendUiElement>
</my:Test>

Output is 0 children. Shouldn't it be 2?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温暖的光 2024-10-04 06:19:10

内容未初始化,因此在初始化时对对象进行计数

protected override void OnInitialized(EventArgs e)
{
   base.OnInitialized(e);
   Console.WriteLine(VisualTreeHelper.GetChildrenCount((UIElement)e.NewValue));
}

,您将得到计数 2

The content is no Initialized so count the object on initialization

protected override void OnInitialized(EventArgs e)
{
   base.OnInitialized(e);
   Console.WriteLine(VisualTreeHelper.GetChildrenCount((UIElement)e.NewValue));
}

And you will get count 2

独享拥抱 2024-10-04 06:19:10

我认为它不起作用,因为无论您分配给 TestSendUiElement DependencyProperty 的是什么,它都不会成为 VisualTree 的一部分。所以 VisualTreeHelper.GetChildrenCount(...) 将不起作用。

作为直接替代品,LogicalTreeHelper 应该可以解决问题。

如果您知道对象或 can 的类型,那么最好使用 ItemsControl.ItemsContentControl.Content 等公开属性,但以下情况除外继承自 Panel 的类(它们的 LogicalChildren 属性是内部的)。

如果你很懒,你也可以执行以下操作(未经测试的代码):

<my:Test.TestSendUiElement>
  <ItemsControl Margin="0,2">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <TextBox Height="23" Width="50" Margin="0,0,5,0" />
    <TextBox Height="23" Width="125" />
    <ItemsControl>
</my:Test.TestSendUiElement>

然后将 DP 属性的类型更改为 ItemsControl,现在你可以通过 this.TestSendUIElement.Items 访问子项。 ItemsControl 可能不像面板那么轻量级,但使用 LogicalTreeHelper 可能也不是最佳选择。取决于场景。

I think it doesn't work because whatever you assign to the TestSendUiElement DependencyProperty, it won't be part of the VisualTree. So VisualTreeHelper.GetChildrenCount(...) will not work.

As a direct replacement, LogicalTreeHelper should do the trick.

And if you know the type of the object or can , then it's even better to use exposed properties like ItemsControl.Items, ContentControl.Content and etc., with the exception of classes inheriting from Panel (they're LogicalChildren property is internal).

If you are lazy you could also do the following (untested code):

<my:Test.TestSendUiElement>
  <ItemsControl Margin="0,2">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"/>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <TextBox Height="23" Width="50" Margin="0,0,5,0" />
    <TextBox Height="23" Width="125" />
    <ItemsControl>
</my:Test.TestSendUiElement>

Then you change the type of the DP property to ItemsControl, and now you can access the children via this.TestSendUIElement.Items. An ItemsControl is probably not as lightweight as a panel, but using the LogicalTreeHelper probably wouldn't be optimal either. Depends on the scenario.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文