我正在開發一個簡單的自定義控件,它應該充當菜單系統。它由2個按鈕組成:Back和Home以及上面的菜單項。 該控件模板看起來是這樣的:在UI線程上執行長任務
<ControlTemplate x:Key="FancyColorPickerTemplate">
<menu:BusyDecorator x:Name="BusyDecorator" Style="{StaticResource BusyDecoratorStyle}">
<menu:BusyDecorator.IsBusyIndicatorShowing>
<PriorityBinding>
<Binding Path="IsBusy" RelativeSource="{RelativeSource AncestorType={x:Type CustomControls:Menu}}"/>
</PriorityBinding>
</menu:BusyDecorator.IsBusyIndicatorShowing>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.70*"/>
<RowDefinition Height="0.30*"/>
</Grid.RowDefinitions>
<ItemsControl Grid.Row="0" Name="Part_ItemControl"
ItemTemplateSelector="{StaticResource imgStringTemplateSelector}"
HorizontalAlignment="Center" VerticalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<Button Grid.Row="1" Name="PART_BackButton" FontSize="20" Content="Back" HorizontalAlignment="Left" />
<Button Grid.Row="1" Name="PART_HomeButton" FontSize="20" Content="Home" HorizontalAlignment="Center" />
</Grid>
</menu:BusyDecorator>
</ControlTemplate>
在ItemsControl中有一個ItemTemplateSelector選擇顯示的元素的DataTemplate中(可以是一個按鈕或者一個用戶控件)。 實施例:
<DataTemplate x:Key="ButtonTemplate">
<Grid Margin="10,0,10,0">
<Button Content="{Binding Title}" ></Button>
</Grid>
</DataTemplate>
<DataTemplate x:Key="UserControlTemplate">
<Grid Margin="10,0,10,0">
<CustomControls:ColorPickerUserControl Width="200" Height="200"/>
</Grid>
</DataTemplate>
在代碼隱藏,我檢查被點擊該元件並加載子菜單(通過設置的ItemsControl的ItemsSource屬性)如果需要的話:
void Menu_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ItemsControl itemsControl = GetTemplateChild("Part_ItemControl") as ItemsControl;
object item = GetElementFromPoint(itemsControl, e.GetPosition(itemsControl));
if (item != null && item is MenuItem2)
{
MenuItem2 mi = item as MenuItem2;
if (mi.SubMenu != null)
{
IsBusy = true;
Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
MenuItems = new ObservableCollection<MenuItem2>(mi.SubMenu.Items);
IsBusy = false;
}));
m_MenuStack.Push(mi.SubMenu);
}
else
{
if (!IsBusy)
{
ExecuteAction(mi.Ac);
}
}
}
else
Console.WriteLine("no item found");
}
的的MenuItems在上面的代碼中綁定到ItemsSource屬性,該屬性將重新評估ItemsControl並應用基於DataTemplateSelector的相應DataTemplate。 我的代碼中的問題是在上面的IsBusy屬性中應該顯示BusyDecorator(請參閱xaml),DataTemplate是需要很長時間才能顯示的UserControl。它不工作,因爲我猜UserControl正在UI線程上加載,以及IsBusy屬性在UI線程上觸發一個動作。
我遵循錯誤的方法嗎?有什麼辦法可以做到這一點?
代碼我會建議使用.NET 4.5,然後用異步/等待功能 –
這將是一個很好的解決方案實現它。不幸的是,我們的嵌入式系統只有框架3.5。 – LPL
你可以走很長的路(實際上Async/Await是做什麼的),並把它放在一個單獨的線程中,並實現一個處理程序,當線程加載完成時收到通知 –