WPF 元素与动态生成的 UI 元素绑定
我有一个页面,其中有一个包含 2 列的网格,一列可容纳 80* 宽度,另一列可容纳 20* 宽度。网格下方是一个堆栈面板,我在运行时向其中加载 UI 元素(子堆栈面板)。
我的目标是将堆栈面板的宽度绑定到网格的列。如果动态内容在设计视图中被模拟为静态,则效果非常好,并且堆栈面板会调整大小。但是当应用程序运行时,绑定失败并且宽度未绑定。
有什么方法可以刷新绑定,以便我可以通知堆栈面板引用网格的宽度并配置其大小?
更新: 这就是我的 XAML 的样子:
<Page x:Class="WPFTestApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="resizeGrid"
Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="leftColumn"
Width="80*" />
<ColumnDefinition x:Name="rightColumn"
Width="20*" />
</Grid.ColumnDefinitions>
</Grid>
<StackPanel x:Name="contentPanel"
Grid.Column="0" Grid.Row="0" >
<!-- Dynamic StackPanels are added here -->
</StackPanel>
</Grid>
</Page>
在我的代码中,我创建 StackPanel 元素并将其添加到 contentPanel 中,方法是: contentPanel.Children.Add(...);
不幸的是,我必须在这里使用 StackPanels。 :-(
动态创建的 StackPanel 元素的标记如下(请注意,我使用了 XAML 中已有的绑定到网格):
<StackPanel x:Name="element01"
Orientation="Horizontal"
Width="{Binding ElementName=resizeGrid, Path=ActualWidth}" >
<StackPanel x:Name="leftPanel"
Orientation="Vertical"
Width="{Binding ElementName=leftColumn, Path=ActualWidth}">
<!-- Content goes here -->
</StackPanel>
<StackPanel x:Name="rightPanel"
Orientation="Vertical"
Width="{Binding ElementName=rightColumn, Path=ActualWidth}">
<!-- Content goes here -->
</StackPanel>
</StackPanel>
我的动态 StackPanel 元素的 XAML 代码是通过 XSLT 转换生成的,
请注意 xmlns:x 命名空间动态 StackPanel 也必须完成,因为它是通过 XSLT 生成的。
I have a page in which I have a grid with 2 columns, one accommodating 80* width and the other accommodating 20*. Beneath the grid is a stack panel to which I load UI elements (child stack panels) at runtime.
My objective is to bind the widths of the stackpanels to the columns of the grid. This works perfectly and the stackpenels resize if the dynamic content is mocked to be static in the design view. But when the application is run, the bindings fail and the widths are not bound.
Is there any way to refresh the bindings so that I can notify the stackpanels to refer the widths of the grid and configure its's size?
Updated:
This is what my XAML looks like:
<Page x:Class="WPFTestApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="resizeGrid"
Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="leftColumn"
Width="80*" />
<ColumnDefinition x:Name="rightColumn"
Width="20*" />
</Grid.ColumnDefinitions>
</Grid>
<StackPanel x:Name="contentPanel"
Grid.Column="0" Grid.Row="0" >
<!-- Dynamic StackPanels are added here -->
</StackPanel>
</Grid>
</Page>
In my code, I create StackPanel elements and add it to the contentPanel by saying:
contentPanel.Children.Add(...);
Unfortunately, I HAVE to use StackPanels here. :-(
The markup of a dynamically created StackPanel element is as follows (note that I use a Binding to the grid already in the XAML):
<StackPanel x:Name="element01"
Orientation="Horizontal"
Width="{Binding ElementName=resizeGrid, Path=ActualWidth}" >
<StackPanel x:Name="leftPanel"
Orientation="Vertical"
Width="{Binding ElementName=leftColumn, Path=ActualWidth}">
<!-- Content goes here -->
</StackPanel>
<StackPanel x:Name="rightPanel"
Orientation="Vertical"
Width="{Binding ElementName=rightColumn, Path=ActualWidth}">
<!-- Content goes here -->
</StackPanel>
</StackPanel>
The XAML code for my dynamic StackPanel elements are generated through an XSLT transformation
Note the xmlns:x namespace dynamic StackPanel. This also has to be done because of it being generated through XSLT
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
据我所知,使用
Orientation="Horizontal"
设置StackPanel
的Width
不会产生任何效果。 StackPanel 的大小不超过其内容在其方向上的大小。为什么你“必须”在这里使用
StackPanel
?考虑到您的目标,您几乎肯定需要DockPanel
。您无需绑定或设置任何内容,因为DockPanel
会自动填充单元格。As far as I know setting the
Width
of aStackPanel
withOrientation="Horizontal"
will have no effect. The size of aStackPanel
does not exceed the size of its content in its oriented direction.Why do you "HAVE" to use
StackPanel
s here? You almost certainly wantDockPanel
s, given your objective. You won't have to bind or set anything, because theDockPanel
will fill the cell automatically.尝试绑定 ActualWidth 而不是 Width。
我在上面做了以下更改:
1) 将
leftColumn
设置为contentPanel
的ActualWidth
2) 将
rightColumn
设置为 *3)
contentPanel
HorizontalAlignment 应更改为Stretch
以外的值。这里我把它改成了Left
HTH
Try binding the ActualWidth instead of Width.
The following changes I have done above:
1) Set the
leftColumn
to theActualWidth
of thecontentPanel
2) Set the
rightColumn
to *3)
contentPanel
HorizontalAlignment should be changed other thenStretch
. Here I have changed it toLeft
HTH
我找到了这个问题的解决方案。 (抱歉回复晚了)
我所做的是将“resizeGrid”网格控件剪切并粘贴到“contentPanel”堆栈面板中。
正如我上面提到的,contentPanel 中的内容是通过 XSLT 转换生成的,这肯定会产生命名空间引用问题。我注意到每当加载此窗口时,输出窗口中都会出现“未找到元素...”消息 - 这证明我是对的。
将“resizeGrid”插入“contentPanel”会有所帮助,因为两个控件都位于同一命名空间内,并且可以使用“ElementName”属性引用 PropertyBinding。
感谢您的支持! :-)
I found a solution for this issue. (Sorry for the late response)
What I did was, I cut and pasted the "resizeGrid" Grid control into the "contentPanel" Stackpanel.
As I mentioned above, the contents within the contentPanel are generated through an XSLT transformation and this surely creates a namespace reference issue. I noticed "element not found..." message in the Output window whenever this Window is loaded - this proved me right.
Inserting the "resizeGrid" into the "contentPanel" helped because then both the controls are within the same namespace and can be referenced for a PropertyBinding using "ElementName" attribute.
Thank you for your support! :-)