数日前、別のスレッドから ObservableCollection を更新できなかったため、このスレッドを作成しました。これはスレッドからの解決策でした:
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(delegate
{
TheTVDB theTvdb = new TheTVDB();
foreach (TVSeries tvSeries in theTvdb.SearchSeries("Dexter"))
{
this.Overview.Add(tvSeries);
}
}),
DispatcherPriority.Background);
ただし、デリゲートの実行中に UI がまだフリーズしているため、これは実際の解決策ではないようです。私の推測では、上記は実際には別のスレッドで何も実行せず、代わりにすべてを UI スレッドにディスパッチします。したがって、私が本当にやりたいことは、自分で新しいスレッドを作成し、読み込みを行うことです (これは で行われtheTvdb.SearchSeries()
ます)。次に、結果を反復処理して追加しObservableCollection
ます。これは UI スレッドで行う必要があります。
このアプローチは正しいと思いますか?
結果をロードしてObervableCollectionに追加し、UIがフリーズすることなくリストビューに表示すると考えた以下を思いつきました。
Thread thread = new Thread(new ThreadStart(delegate
{
TheTVDB theTvdb = new TheTVDB();
List<TVSeries> dexter = theTvdb.SearchSeries("Dexter");
foreach (TVSeries tvSeries in dexter)
{
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(delegate
{
this.Overview.Add(tvSeries);
}),
DispatcherPriority.Normal);
}
}));
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
上記はエラーを生成しません。代わりに、何も起こりません。UI はフリーズしませんが、更新されません。のオブジェクトがOverview
UI に表示されず、バインドが正しいことをテストしました。ObservableCollection
オブジェクトをロードして別のスレッドに追加しないと、オブジェクトは正しく表示されます。
私が試した別の解決策は、この回答から同様の質問へのMTObservableCollectionを使用することです。のそのサブクラスを使用するときObservableCollection
、私は自分で何もディスパッチしませんでした。これにより、次のエラーが発生しました。
DependencyObject と同じ Thread に DependencySource を作成する必要があります。
誰でも私ができる方法を教えてください:
- 別のスレッドに何かをロードする
- ステップ 1 の結果を使用して、リストビューにバインドされている ObservableCollection を更新します。
- UI がフリーズせずに UI に結果が表示されるようにする
あなたが私をさらに助けてくれることを願っています。
更新:
<UserControl
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:acb="clr-namespace:AttachedCommandBehavior"
mc:Ignorable="d"
x:Class="TVSeriesLibrary.OverviewView"
x:Name="UserControl"
d:DesignWidth="512"
d:DesignHeight="480">
<UserControl.Resources>
<DataTemplate x:Key="CoverTemplate">
<StackPanel Orientation="Horizontal">
<Image Width="82" Height="85" Stretch="Fill" Source="{Binding Cover}" Margin="10,10,0,10"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="#515050">
<Grid.Resources>
<ResourceDictionary>
<Style x:Key="ItemContStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="Background" Value="#282828" />
<Setter Property="Margin" Value="0,0,0,5" />
<Setter Property="Padding" Value="0" />
</Style>
</ResourceDictionary>
</Grid.Resources>
<ListView Height="112"
Width="488"
Margin="12,150,12,218"
Foreground="#ffffff"
Background="#515050"
VerticalContentAlignment="Center"
BorderThickness="0"
ItemTemplate="{StaticResource CoverTemplate}"
ItemsSource="{Binding Overview}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
<ListView Height="170"
Margin="10,298,10,0"
VerticalAlignment="Center"
Foreground="#ffffff"
Background="#515050"
VerticalContentAlignment="Center"
BorderThickness="0"
Width="488" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Path=Overview}"
SelectedItem="{Binding Path=SelectedTVSeries}"
ItemContainerStyle="{StaticResource ItemContStyle}">
<ListView.Resources>
<ResourceDictionary>
<Style x:Key="hiddenStyle" TargetType="GridViewColumnHeader">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</ResourceDictionary>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Cover" Width="auto" HeaderContainerStyle="{StaticResource hiddenStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=Cover}" Height="50" Margin="-6,0,0,0" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Title" Width="200" HeaderContainerStyle="{StaticResource hiddenStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Year" Width="100" HeaderContainerStyle="{StaticResource hiddenStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=DisplayYear}"></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Button" Width="135" HeaderContainerStyle="{StaticResource hiddenStyle}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content="Details" Width="100" Height="20" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</UserControl>