0

C#/XAML を使用して Windows ストア アプリを構築しています。

ItemsSource にバインドされた単純な ListView があります。各項目の構造を定義し、ContentControl と TextBlock を含む DataTemplate があります。

アイテムが選択されたときに、TextBlock の前景色を変更したいと考えています。誰も私がこれを行う方法を知っていますか?

<ListView Grid.Column="1" 
              ItemsSource="{Binding Categories}" 
              ItemContainerStyle="{StaticResource CategoryListViewItemStyle}"
              Background="{StaticResource DeepRedBrush}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <ContentControl Content="{Binding Id, Converter={StaticResource Cat2Icon}}" HorizontalAlignment="Left" VerticalAlignment="Center" Width="110" Foreground="#FF29BCD6"/>
                    <TextBlock x:Name="catName" HorizontalAlignment="Left" Margin="0" TextWrapping="Wrap" Text="{Binding Name}" Grid.Column="1" VerticalAlignment="Center" FontSize="18.667" 
                               Foreground="White"/>

                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

現時点では「白」に設定されているため、必要なのは、リストビュー内の項目の選択状態に応じて Foreground プロパティを変更するバインディング式だけです。

4

2 に答える 2

2

これはあなたが求めていることを行います。

この XAML の使用

<Grid x:Name="LayoutRoot" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView x:Name="MyListView" ItemsSource="{Binding Items}" SelectionMode="Single" SelectedItem="{Binding Selected, Mode=TwoWay}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid Height="100" Width="300">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="100" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Ellipse x:Name="ellipse">
                        <Ellipse.Fill>
                            <SolidColorBrush Color="{Binding Color}" />
                        </Ellipse.Fill>
                    </Ellipse>
                    <TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="10" Text="{Binding Title}" Style="{StaticResource HeaderTextBlockStyle}" />
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

そして、このコードビハインド:

public class MyModel : BindableBase
{
    string _Title = default(string);
    public string Title { get { return _Title; } set { SetProperty(ref _Title, value); } }

    Color _Color = Colors.White;
    public Color Color { get { return _Color; } set { SetProperty(ref _Color, value); } }
}

public class MyViewModel : BindableBase
{
    public MyViewModel()
    {
        var items = Enumerable.Range(1, 10)
            .Select(x => new MyModel { Title = "Title " + x.ToString() });
        foreach (var item in items)
            this.Items.Add(item);
    }

    MyModel _Selected = default(MyModel);
    public MyModel Selected
    {
        get { return _Selected; }
        set
        {
            if (this.Selected != null)
                this.Selected.Color = Colors.White;
            SetProperty(ref _Selected, value);
            value.Color = Colors.Red;
        }
    }

    ObservableCollection<MyModel> _Items = new ObservableCollection<MyModel>();
    public ObservableCollection<MyModel> Items { get { return _Items; } }
}

public abstract class BindableBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void SetProperty<T>(ref T storage, T value, [System.Runtime.CompilerServices.CallerMemberName] String propertyName = null)
    {
        if (!object.Equals(storage, value))
        {
            storage = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    protected void RaisePropertyChanged([System.Runtime.CompilerServices.CallerMemberName] String propertyName = null)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

データ テンプレートが更新されます。

簡単に言いたいのですが、ViewModel を使用してリストのコンテンツを更新するのが、最も簡単で軽量な方法です。この場合、楕円にバインドされている色を更新しています。ただし、これが複雑な一連の変更である場合は、代わりにスタイルを設定するだけかもしれません。もう 1 つのオプションは、テンプレート内のコントロール セット全体を表示および非表示にすることです。ただし、グリッドが再描画されるまで再レンダリングされないため、データ テンプレートを変更することはできません。これは、やりたいことではありません。

楕円の色を変更するのと同じように、質問で尋ねたように TextBlock Foreground を変更できます。いずれにせよ、これにより、最もエレガントな方法で必要なものが得られます。

頑張ってください!

于 2013-12-05T18:29:34.833 に答える
1

SelectionChangedでイベントを処理し、以前に選択したアイテムと新しく選択したアイテムの を変更するには、 にバインドされているビュー モデルの値を変更ListViewします。ForegroundSelectedItemForeground

Jerry Nixon のブログ投稿のように+をTextBlock使用して Foreground を直接変更することもできます。変更されたアイテム ビューはリサイクルされ、コレクション内の別のアイテムに使用される可能性があります。ListView.ItemContainerGenerator.ContainerFromItem(ListView.SelectedItem)VisualTreeHelperListViewForeground

別のオプションは、多くの方法で行うことができる親ForegroundIsSelectedプロパティにバインドすることです。ListViewItemたとえば、全体DataTemplateを aに入れ、そのコントロールの にUserControlバインドできます。問題は、依存関係プロパティではないと思いますが、(プロパティを定義する基本クラス) にイベントが表示されないため、このルートに進むのは難しい場合があります。これらをバインドする別の方法は、添付の依存関係プロパティまたは動作を定義して、そのバインディングを設定することですが、これは複雑です (ただし、ここで使用できるものは既に作成しています)。ForegroundParentParentParentChangedFrameworkElementUserControlParent

ListView.ItemContainerStyle最後に、値を変更して変更できSelectedBackgroundます。それが機能する場合、それは理想的なソリューションです。

    <Style TargetType="ListViewItem">
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
        <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="TabNavigation" Value="Local"/>
        <Setter Property="IsHoldingEnabled" Value="True"/>
        <Setter Property="Margin" Value="0,0,18,2"/>
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="VerticalContentAlignment" Value="Top"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListViewItem">
                    <ListViewItemPresenter CheckHintBrush="{ThemeResource ListViewItemCheckHintThemeBrush}" CheckBrush="{ThemeResource ListViewItemCheckThemeBrush}" ContentMargin="4" ContentTransitions="{TemplateBinding ContentTransitions}" CheckSelectingBrush="{ThemeResource ListViewItemCheckSelectingThemeBrush}" DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackgroundThemeBrush}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" FocusBorderBrush="{ThemeResource ListViewItemFocusBorderThemeBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" PointerOverBackgroundMargin="1" PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" PointerOverBackground="{ThemeResource ListViewItemPointerOverBackgroundThemeBrush}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" SelectedPointerOverBorderBrush="{ThemeResource ListViewItemSelectedPointerOverBorderThemeBrush}" SelectionCheckMarkVisualEnabled="True" SelectedForeground="{ThemeResource ListViewItemSelectedForegroundThemeBrush}" SelectedPointerOverBackground="{ThemeResource ListViewItemSelectedPointerOverBackgroundThemeBrush}" SelectedBorderThickness="{ThemeResource ListViewItemCompactSelectedBorderThemeThickness}" SelectedBackground="{ThemeResource ListViewItemSelectedBackgroundThemeBrush}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
于 2013-12-04T18:07:46.880 に答える