代码之家  ›  专栏  ›  技术社区  ›  MetaColon

ListView ItemContainerStyle的WPF绑定背景

  •  1
  • MetaColon  · 技术社区  · 6 年前

    我有一个 UserControl ( FahrtControl.xaml )有一个 ListView . 这个 用户控件 ItemsControl 在我的 MainWindow.xaml . 这个 MainWindow 有自己的视图模型和 FahrtControl 有自己的视图模型。我现在要绑定 Listview 项目到 Brush 的ViewModel中的属性 华氏温度控制 .

    以下是我的代码的相关部分:

    主窗口.xaml:

    <Window x:Class="WpfFrontend.Forms.Main.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:WpfFrontend.Forms.Main"
        xmlns:fahrtControl="clr-namespace:WpfFrontend.Controls.FahrtControl"
        mc:Ignorable="d">
    <Window.DataContext>
        <local:MainViewModel />
    </Window.DataContext>
    <Window.Resources>
        <DataTemplate DataType="{x:Type fahrtControl:FahrtControlViewModel}">
            <fahrtControl:FahrtControl />
        </DataTemplate>
    </Window.Resources>
    <ItemsControl ItemsSource="{Binding Fahrten, UpdateSourceTrigger=PropertyChanged}" />
    

    主视图模型.cs:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    using Backend;
    
    using DatabaseCommunication;
    
    using WpfFrontend.Annotations;
    using WpfFrontend.Controls.FahrtControl;
    
    
    namespace WpfFrontend.Forms.Main
    {
        public class MainViewModel : INotifyPropertyChanged
        {
            public MainViewModel ()
            {
                SyncFahrten ();
            }
    
            private void SyncFahrten ()
            {
                var fahrtenPromise =
                    MainUtility.GetFahrtenToRangeAsync (GlobalProperties.Start, GlobalProperties.Start.AddDays (6));
    
                fahrtenPromise.Task.GetAwaiter ().OnCompleted (() =>
                {
                    AddFahrten (fahrtenPromise.Task.Result);
                });
            }
    
            private void AddFahrten (List <ExtendedFahrt> fahrten)
            {
                    foreach (var fahrtControlViewModel in
                        fahrten.Select (fahrt =>
                                     {
                                         return new FahrtControlViewModel (
                                             Brushes.Red, Brushes.Red, Brushes.White,
                                             fahrt.Ort,
                                             new ObservableCollection <string>
                                             {
                                                 fahrt.Bemerkung
                                             }, new ObservableCollection <KundeDisplay> (fahrt.Kunden));
                                     }))
                        Fahrten.Add (fahrtControlViewModel);
    
                OnPropertyChanged ("");
            }
    
    
    
            private ObservableCollection <FahrtControlViewModel> _fahrten =
                new ObservableCollection <FahrtControlViewModel> ();
    
            public ObservableCollection <FahrtControlViewModel> Fahrten
            {
                get => _fahrten;
                set
                {
                    if (Equals (value, _fahrten))
                        return;
                    _fahrten = value;
                    OnPropertyChanged ();
                }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            [NotifyPropertyChangedInvocator]
            protected virtual void OnPropertyChanged ([CallerMemberName] string propertyName = null) =>
                PropertyChanged?.Invoke (this, new PropertyChangedEventArgs (propertyName));
        }
    }
    

    fahrtcontrol.xaml(法赫控制.xaml):

    <UserControl x:Class="WpfFrontend.Controls.FahrtControl.FahrtControl"
                 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:WpfFrontend.Controls.FahrtControl"
                 mc:Ignorable="d"
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.Resources>
            <Style x:Key="HeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
                <Setter Property="Visibility" Value="Collapsed" />
            </Style>
        </UserControl.Resources>
        <ListView ItemsSource="{Binding Kunden}"
                  Background="{Binding KundenBrush, UpdateSourceTrigger=PropertyChanged}">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="Background" Value="{Binding DataContext.KundenBrush}" />
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView ColumnHeaderContainerStyle="{StaticResource HeaderStyle}">
                    <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" />
                </GridView>
            </ListView.View>
        </ListView>
    </UserControl>
    

    fahrtcontrolviewmodel.cs:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Windows.Media;
    
    using Backend;
    
    using WpfFrontend.Annotations;
    using WpfFrontend.Misc;
    
    
    namespace WpfFrontend.Controls.FahrtControl
    {
        public class FahrtControlViewModel : INotifyPropertyChanged
        {
            private Brush                               _kundenBrush = Brushes.Red;
            private ObservableCollection <KundeDisplay> _kunden;
    
            /// <inheritdoc />
            public FahrtControlViewModel (
                Brush                               kundenBrush,
                ObservableCollection <KundeDisplay> kunden)
            {
                Kunden         = kunden;
                KundenBrush    = kundenBrush;
            }
            public Brush KundenBrush
            {
                get => _kundenBrush;
                set
                {
                    if (value.Equals (_kundenBrush))
                        return;
                    _kundenBrush = value;
                    KundenDark   = _kundenBrush.IsDark ();
    
                    OnPropertyChanged ();
                }
            }
    
            public ObservableCollection <KundeDisplay> Kunden
            {
                get => _kunden;
                set
                {
                    if (Equals (value, _kunden))
                        return;
                    _kunden = value;
                    OnPropertyChanged ();
                }
            }
    
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            [NotifyPropertyChangedInvocator]
            protected virtual void OnPropertyChanged ([CallerMemberName] string propertyName = null) =>
                PropertyChanged?.Invoke (this, new PropertyChangedEventArgs (propertyName));
        }
    }
    

    我已经尝试了以下方法:

    用户控件 所以它一定和样式标签有关,不是吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Bizhan    6 年前

    DataContext 属于 ListView.ItemContainerStyle ListView 的。您可以找到具有其元素名称的正确数据上下文:

    <UserControl x:Class="WpfFrontend.Controls.FahrtControl.FahrtControl"
                 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:WpfFrontend.Controls.FahrtControl"
                 mc:Ignorable="d"
    
                 <!--      -->
                 x:Name="root"
                 <!--      -->
    
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.Resources>
            <Style x:Key="HeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
                <Setter Property="Visibility" Value="Collapsed" />
            </Style>
        </UserControl.Resources>
        <ListView ItemsSource="{Binding Kunden}"
                  Background="{Binding KundenBrush, UpdateSourceTrigger=PropertyChanged}">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
    
                 <!--      -->
                    <Setter Property="Background" Value="{Binding ElementName=root, Path=DataContext.KundenBrush}" />
                 <!--      -->
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView ColumnHeaderContainerStyle="{StaticResource HeaderStyle}">
                    <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" />
                </GridView>
            </ListView.View>
        </ListView>
    </UserControl>
    

    或者通过跟踪元素树:

    <UserControl x:Class="WpfFrontend.Controls.FahrtControl.FahrtControl"
                 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:WpfFrontend.Controls.FahrtControl"
                 mc:Ignorable="d"
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.Resources>
            <Style x:Key="HeaderStyle" TargetType="{x:Type GridViewColumnHeader}">
                <Setter Property="Visibility" Value="Collapsed" />
            </Style>
        </UserControl.Resources>
        <ListView ItemsSource="{Binding Kunden}"
                  Background="{Binding KundenBrush, UpdateSourceTrigger=PropertyChanged}">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
    
                 <!--      -->
                    <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource AncestorType=FahrtControl}, Path=DataContext.KundenBrush}" />
                 <!--      -->
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.View>
                <GridView ColumnHeaderContainerStyle="{StaticResource HeaderStyle}">
                    <GridViewColumn DisplayMemberBinding="{Binding Name}" Header="Name" />
                </GridView>
            </ListView.View>
        </ListView>
    </UserControl>