今天早上我問了一個問題here並且做了一個簡單的工作示例,給了我一個不同於預期的行爲。爲什麼DataBinding不會傳播到UserControl
全工作樣品在GitHub。主要部分代碼如下。
在這種情況下,如果UserControl直接用作窗口的子窗口,則該命令永遠不會傳播到任何UserControl。如果UserControl用作ListBox ItemTemplate的DataTemplate,它也不起作用。
我還包括一個黑客按鈕來解決命令到達UserControls的問題。黑客來自StackOverflow。
但是使用hack並沒有解釋爲什麼UserControl沒有收到命令(沒有它)並且使用這個hack也破壞了良好編碼的第一條規則:「高內聚和低耦合」。應該在窗口代碼中使用hack以便管理UserControl中的Command,我的想法是它應該在默認情況下發生。
爲什麼命令不會默認傳播給UserControl,我該怎麼做才能以乾淨的方式將命令傳播到UserControl?
注意:在UserControl中只使用一個CommandBinding(刪除一個或另一個)不能解決問題。
部分代碼:
<Window x:Class="CommandRoutingIntoItemTemplate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:CommandRoutingIntoItemTemplate"
xmlns:system="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<local:UserControlTest></local:UserControlTest>
<ListBox Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Aqua" BorderThickness="2">
<local:UserControlTest></local:UserControlTest>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Items>
<system:String>1</system:String>
<system:String>2</system:String>
</ListBox.Items>
</ListBox>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<Button Command="local:Commands.CommandTest">Put focus on TestBlock and click here to see if command occurs</Button>
<Button Click="AddHack">Hack</Button>
</StackPanel>
</Grid>
</Window>
用戶控件:
<UserControl x:Class="CommandRoutingIntoItemTemplate.UserControlTest"
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:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CommandRoutingIntoItemTemplate"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.CommandBindings>
<CommandBinding Command="local:Commands.CommandTest" CanExecute="CommandTestCanExecuteUserControl" Executed="CommandTestExecuteUserControl"></CommandBinding>
</UserControl.CommandBindings>
<Grid>
<TextBox Text="UserControlTest">
<TextBox.CommandBindings>
<CommandBinding Command="local:Commands.CommandTest" CanExecute="CommandTestCanExecuteTextBox" Executed="CommandTestExecuteTextBox"></CommandBinding>
</TextBox.CommandBindings>
</TextBox>
</Grid>
</UserControl>
很好的解釋!十分感謝!完美的作品。你知道我是否可以在UserControl上做些什麼來確保它始終適用於每種類型的用法?雖然現在工作正常,但我可能想在其他地方使用我的UserControl,但我必須記住這一點。這聽起來是一個更好的解決方案,只在一個常見的地方編寫代碼(UserControl),以確保在每種情況下的正確使用。 –
我也用menuItem測試過,它工作正常可能是因爲Menu元素有你提出給我的修正:FocusManager.IsFocusScope設置爲true?這是我必須知道和記住的事情;-)? –
@EricOuellet完全正確。 MenuItems顯示在具有自己的焦點範圍的彈出窗口中。 – ghord