我最终这样做了:
<UserControl x:Class="MyProject.FooBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:userControls="clr-namespace:MyProject.UserControls"
Loaded="Loaded"> <!-- notice -->
<userControls:Test>
<TextBox Initialized="FooInitialized" />
<Button Initialized="AnotherInitialized" />
</userControls:Test>
和代码:
// This for every initialization, all we do is set names after the elements are initialized.
private void FooInitialized(object sender, EventArgs e)
{
((TextBox) sender).Name = "Foo";
}
// Here when the entire junk is loaded, we set the necessary commands.
private void Loaded(object sender, EventArgs e)
{
// Find elements.
var button = UIHelper.FindChild<Button>(this, "Bar");
var textBox = UIHelper.FindChild<TextBox>(this, "Foo");
// Set up bindings for button.
button.Command = ((FooViewModel) DataContext).FooCommand;
button.CommandParameter = textBox;
}
UIHelper
来自https://stackoverflow.com/a/1759923/283055。_ 该按钮的名称也与文本框相同。
基本上所有名称都是通过Initialized
事件设置的。唯一的缺点是您必须在代码中引用名称,这就是为什么我在整个组件加载后通过代码设置命令的原因。我发现这是代码和 UI 标记之间的最佳折衷方案。