1

ThreadSafeObservableCollectionにバインドされているリストビューがあります。これらの各アイテムの背景は、カラーコンバーターを介して実行される列挙型に設定されています。これら2つの設定のコードは次のとおりです。

<UserControl.Resources>
    <EncoderView:EncoderStatusToColorConverter x:Key="ColorConverter"/>
    <Style x:Key="ItemContStyle" TargetType="{x:Type ListViewItem}">
        <Setter Property="Background" Value="{Binding Converter={StaticResource ColorConverter}}" />
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
</UserControl.Resources>

私がしたいのは、listviewItemの背景色が列挙値に基づいて赤-黄-緑に変わることです。これは、ビジネスロジックルールに基づいて更新されます。これは現在機能していますが、アイテムの初期表示のみです。listItemViewがバインドされているオブジェクトの「Status」プロパティを変更しても、背景が更新されません。コレクションからオブジェクトを削除し、ステータスを変更してから、コレクションに再度追加すると、背景が更新されます。
オブジェクトIPropertyNotifyを作成し、statusプロパティchanged setterにイベントをスローしようとしましたが、機能しませんでした。

リストビューアイテムの背景を更新するために私がしなければならない特別なことがあるかどうか誰かが知っていますか。この問題を解決する方法については、他のアイデアも受け付けています。ありがとうございます。これがListViewのXAMLです。EncoderService.Encodersは、エンコーダーオブジェクトの私のThreadSafeObservableCollectionです。

        <ListView  AutomationProperties.AutomationId="FinishScreen"  
                   ItemsSource="{Binding Path=EncoderService.Encoders}" 
                   x:Name="DataListView" Grid.RowSpan="1" Grid.Row="1" Margin="5"
                   ItemContainerStyle="{StaticResource ItemContStyle}"
                   Background="Azure">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="MAC">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ContentControl Content="{Binding Path=MAC}" ToolTip="{Binding Path=MAC}"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="IDF">...
4

4 に答える 4

2

問題は、Binding to Background が Encoder オブジェクト全体を取得していることです。これは、削除して追加しない限り変更されません。Encoder が INotifyPropertyChanged を実装している場合でも、Binding は引き続き Encoder オブジェクト全体を調べており、Encoder のどのプロパティが EncoderStatusToColorConverter に関連しているかを知る方法がないため、それ自体は更新されません。

あなたの場合の解決策は、背景のバインディングの範囲を EncoderStatusToColorConverter に関連するプロパティ (またはプロパティ) だけに狭めることです。Binding のパス内のすべてのプロパティは、更新を監視されます。たとえば、ステータスのみが必要な場合は次のようになります。

<Style x:Key="ItemContStyle" TargetType="{x:Type ListViewItem}">
    <Setter Property="Background" Value="{Binding Path=Status, Converter={StaticResource ColorConverter}}" />
    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>

この場合、Encoder に INotifyPropertyChanged を実装し、Status が変化するたびに通知すると、Binding が更新されます。これは、EncoderStatusToColorConverter を更新して、ステータス タイプのみを取得する必要があることも意味します。

于 2008-12-25T20:07:32.253 に答える
1

DataTemplateSelectorを使用してみましたか?これを使用して、ListBoxItemに使用するテンプレートを変更します。これは、基本的に、プロパティに基づいて前景色を変更するだけです。ページの読み込み後にデータが変更されるというシナリオは試していませんが、なぜ機能しないのかわかりません。

私はこのクラスを持っています:

public class UniqueWordDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item != null && item is WordScore)
        {
            WordScore word = item as WordScore;

            FrameworkElement elem = container as FrameworkElement;

            if (word.IsUnique)
                return
                    elem.FindResource("UniqueWordListTemplate") as DataTemplate;
            else
                return
                    elem.FindResource("WordListTemplate") as DataTemplate;
        }

        return null;
    }
}

私のコントロールのリソースには、次の行があります。

    <UserControl.Resources>
    ...
    <my:UniqueWordDataTemplateSelector x:Key="myDataTemplateSelector"/>

ここには2つのテンプレートもあります。

    <DataTemplate x:Key="WordListTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="210" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Path=Word}" Background="{x:Null}" Foreground="White"/>
            <TextBlock Text="{Binding Path=Score}" Background="{x:Null}" Foreground="White"/>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="UniqueWordListTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="210" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding Path=Word}" Background="{x:Null}" Foreground="Gold"/>
            <TextBlock Text="{Binding Path=Score}" Background="{x:Null}" Foreground="White"/>
        </Grid>
    </DataTemplate>

次に、リストボックスに次を使用します。

   <ListBox x:Name="PlayerList2" ItemTemplateSelector="{DynamicResource myDataTemplateSelector}" IsSynchronizedWithCurrentItem="True" Background="#FF252525"/>
于 2008-12-23T17:45:06.863 に答える
0

私はこのアプローチが好きで、それを説得しようとしますが、すぐにわかる唯一の問題は、表形式のデータを表示しているため、GridViewを使用していることです。私は列ヘッダーが好きです。しかし、私はそれを回避する方法を見つけることができると思います。おそらく、自分の列ヘッダーを手動で配置するだけです。

ListItemは、データテンプレートを更新する必要があることをどのように通知されますか?これは、制限されたアイテムのいずれかでPropertyChangedイベントを受信するたびに発生しますか?

于 2008-12-23T18:06:23.277 に答える
0

INotifyPropertyChanged を実装する必要があるものについて混乱する可能性があると思います。

だから私は「エンコーダー」オブジェクトの ObservableCollection を持っています。ObservableCollection は明らかに観察可能であり、何かを追加したり削除したりすると、更新されます。ただし、各「エンコーダー」のプロパティは更新されていません。私が理解していることから、「エンコーダー」クラスは INotifyPropertyChanged を実装し、イベントでプロパティの名前を送信する必要があることを意味します。これは正しい考え方ですか?現時点では機能していないためです。さらにコードを投稿する前に、理論が正しいことを確認したいと思います。

ありがとう

于 2008-12-23T20:34:53.057 に答える