我有一个带有UserControlFahrtControl.xaml(ListView)。此UserControl绑定(bind)到我的ItemsControl中的MainWindow.xamlMainWindow具有自己的ViewModel,而FahrtControl具有其自己的ViewModel。我现在想将Listview项的Background绑定(bind)到Brush的ViewModel中的FahrtControl属性。

这是我的代码的相关部分:

MainWindow.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}" />

MainViewModel.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:
<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));
    }
}

我已经尝试了以下方法:
  • How i change ListView Item Background Color according to listview item HarfNotu value in wpf
  • https://social.msdn.microsoft.com/Forums/vstudio/en-US/b25973bb-9e9c-4a99-8234-39a042e0a478/apply-styles-dynamically-to-buttons-in-xaml?forum=wpf
  • How do I set the background color of a listview item in WPF using databinding?
  • https://msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol.contenttemplateselector%28v=vs.110%29.aspx
  • https://social.msdn.microsoft.com/Forums/vstudio/en-US/4df9f644-9bfa-4913-acc6-0bce711b70ec/setting-wpf-listview-background-when-disabled-and-empty?forum=wpf
  • Binding the value of a Setter Property in WPF
  • WPF Error 40 BindingExpression path error: property not found on 'object'
  • How to set background of listview?

  • 如果我不得不猜测与该主题略相关的其他建议。我在这里做错了什么?它是否与我在ItemsControl中使用UserControl有关?我的UserControl内还存在其他没有由样式标签包围的属性绑定(bind),因此它必须与样式标签有关,不是吗?

    最佳答案

    DataContextListView.ItemContainerStyleListView的ojit_code不同。您可以使用其元素名称找到正确的数据上下文:

    <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>
    

    关于c# - WPF绑定(bind)ListView ItemContainerStyle的背景,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50593968/

    10-17 01:15