如何访问 WPF 模板中的控件并为其提供默认值?
我正在努力处理控制模板。我目前正在构建一个用户界面,其中有几个窗格,这些窗格本质上是由更基本的控件构建的。
下面是我们的一个构造窗格现在的样子:
<Grid>
<StackPanel>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Template="{StaticResource StringCtrl}" Content="Cash Event Value:"/>
</ContentControl>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Template="{StaticResource RateCtrl}"></ContentControl>
</ContentControl>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Grid.Row="0" Template="{StaticResource FromCtrl}"></ContentControl>
</ContentControl>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Grid.Row="0" Template="{StaticResource StartEndDateCtrl}"></ContentControl>
</ContentControl>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Grid.Row="0" Template="{StaticResource ComboStringCtrl}">Applicable Size:</ContentControl>
</ContentControl>
</StackPanel>
</Grid>
下面是 StringCtrl 的模板作为示例:
<ControlTemplate x:Key="StringCtrl" TargetType="ContentControl">
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Name="ctrlText" Margin="0,0,5,0" Text="{TemplateBinding Content}"></TextBlock>
<TextBox Name="ctrlDefaultValue" Grid.Column="1" />
</Grid>
</ControlTemplate>
正如您从模板中看到的,它实际上只是一个标签和一个文本框。现在假设我想为文本框提供默认值并对用户输入执行验证,但我想从父“构造”窗格提供该上下文并将其绑定到模板内的各个元素。我该怎么做呢?
I'm struggling with control templates. I'm currently building a UI which has several panes which are essentially build out of more basic controls.
here's how one of our construction panes looks like right now:
<Grid>
<StackPanel>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Template="{StaticResource StringCtrl}" Content="Cash Event Value:"/>
</ContentControl>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Template="{StaticResource RateCtrl}"></ContentControl>
</ContentControl>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Grid.Row="0" Template="{StaticResource FromCtrl}"></ContentControl>
</ContentControl>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Grid.Row="0" Template="{StaticResource StartEndDateCtrl}"></ContentControl>
</ContentControl>
<ContentControl Template="{StaticResource ConstructionBorderCtrl}">
<ContentControl Grid.Row="0" Template="{StaticResource ComboStringCtrl}">Applicable Size:</ContentControl>
</ContentControl>
</StackPanel>
</Grid>
Here's a template for the StringCtrl as an example:
<ControlTemplate x:Key="StringCtrl" TargetType="ContentControl">
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Name="ctrlText" Margin="0,0,5,0" Text="{TemplateBinding Content}"></TextBlock>
<TextBox Name="ctrlDefaultValue" Grid.Column="1" />
</Grid>
</ControlTemplate>
As you can see from the template it's really just a label and a textbox. Now let's say I wanted to provide a default value to the text box as well as perform validation on user input, but I want to provide that context from the parent Construction pane and bind it to the individual elements inside the templates. How would I go about doing that?
这当然是我以前从未见过的设计。我认为 UserControls 或其他类型的自定义控件比 ControlTemplate 方法更适合此目的。
但如果你确实想走这条路,如果模板中的结构/命名有一定的一致性,我可能会看到一个适合你的行为 - 你可以在行为上设置属性,并且行为可以通过其 AssociatedObject 访问控件属性能够设置子项的值并进行验证。
不过对我来说似乎有很多工作要做。
This is certainly a design I've never seen before. I'd think UserControls or some other type of custom control would work better for this than the ControlTemplate approach.
But if you definitely want to go down this route, I could maybe see a Behavior working for you if there's some consistency to your structure/naming in the templates - you can set properties on the behavior and the behavior can access the control via its AssociatedObject property to be able to set the values of the children and do validation.
Seems like a lot of work to me though.