私はこのようにそれをすることになった:
<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マークアップの間の最良の妥協点であることがわかりました。