【问题标题】:Binding a property to change the listbox items foreground individually for each item绑定属性以单独更改每个项目的列表框项目前景
【发布时间】:2012-01-01 15:06:49
【问题描述】:

我正在尝试为每个项目单独更改 ListBox 中项目的前景色,我已经发布了一个类似的问题,但这个问题更具体。

我希望为添加到ListBox的每个项目保留颜色的状态,所以我尝试创建一个属性(在本例中为“HotkeysForeground”),绑定它并在项目添加时更改颜色"HotkeyManager_NewHotkey" 事件,它改变ListBox中所有项目的前景色的问题。

我怎样才能按项目做到这一点?

这是我使用的 ViewModel。

namespace Monkey.Core.ViewModel
{
    using System;
    using System.Collections.ObjectModel;
    using System.Windows.Media;

    using Monkey.Core.SystemMonitor.Accessibility;
    using Monkey.Core.SystemMonitor.Input;

    public class MainWindowViewModel : WorkspaceViewModel
    {
        private readonly FocusManager _focusManager;

        private readonly HotkeyManager _hotkeyManager;

        private readonly ObservableCollection<string> _hotkeys;

        private Color _foregroundColor;

        private string _title;

        public MainWindowViewModel()
        {
            _hotkeys = new ObservableCollection<string>();

            _hotkeyManager = new HotkeyManager();
            _hotkeyManager.NewHotkey += HotkeyManager_NewHotkey;

            _focusManager = new FocusManager();
            _focusManager.Focus += FocusManager_Focus;
        }

        public Color HotkeysForeground
        {
            get
            {
                return _foregroundColor;
            }
            set
            {
                _foregroundColor = value;

                OnPropertyChanged(() => HotkeysForeground);
            }
        }

        public ReadOnlyObservableCollection<string> Hotkeys
        {
            get
            {
                return new ReadOnlyObservableCollection<string>(_hotkeys);
            }
        }

        public string Title
        {
            get
            {
                return _title;
            }
            set
            {
                _title = value;

                OnPropertyChanged(() => Title);
            }
        }

        protected override void OnDispose()
        {
            base.OnDispose();

            _hotkeyManager.Dispose();

            _focusManager.Dispose();
        }

        private void FocusManager_Focus(object sender, FocusManagerEventArgs e)
        {
            Title = e.Title;
        }

        private void HotkeyManager_NewHotkey(object sender, EventArgs eventArgs)
        {
            HotkeysForeground = _hotkeys.Count <= 2 ? Colors.Blue : Colors.Brown;

            _hotkeys.Clear();

            foreach (var hotkey in _hotkeyManager.GetHotkeys())
            {
                _hotkeys.Add(hotkey);
            }
        }
    }
}

这是视图。

<Window x:Class="Monkey.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:System="clr-namespace:System;assembly=mscorlib"
        Title="{Binding Mode=OneWay, Path=Title, UpdateSourceTrigger=PropertyChanged}" Height="200" Width="200" ShowInTaskbar="False" WindowStyle="ToolWindow" Topmost="True" ResizeMode="CanResizeWithGrip" AllowsTransparency="False">
    <Window.Resources>
        <SolidColorBrush Color="{Binding HotkeysForeground}" x:Key="HotkeysBrush"/>
    </Window.Resources>
    <ListBox 
        Canvas.Left="110" 
        Canvas.Top="74" 
        Name="HotkeyList" 
        Height="Auto" Width="Auto" HorizontalContentAlignment="Left" 
        BorderThickness="0"
        ScrollViewer.CanContentScroll="False"
        ScrollViewer.HorizontalScrollBarVisibility="Disabled"
        ScrollViewer.VerticalScrollBarVisibility="Disabled"
        ItemsSource="{Binding Path=Hotkeys}" VerticalAlignment="Stretch" VerticalContentAlignment="Center" FontSize="20">
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="IsEnabled" Value="False" />
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Label Content="{Binding}" Foreground="{StaticResource HotkeysBrush}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Window>

提前谢谢你。

【问题讨论】:

  • 尝试将您的前台绑定设为“一次性”绑定。
  • 不,这样做会导致恒定的蓝色项目。

标签: c# wpf data-binding mvvm listbox


【解决方案1】:

对我来说,这听起来像是糟糕的设计。如果您有比热键字符串更多的数据,只需创建一个类并将颜色与显示字符串一起存储为单独的属性。

编辑:示例:

public class HotkeyViewModel
{
    private readonly string _DisplayString;
    public string DisplayString { get { return _DisplayString; } }

    private readonly Color _Color;
    public Color Color { get { return _Color; } }

    public HotkeyViewModel(string displayString, Color color)
    {
        _DisplayString = displayString;
        _Color = color;
    }
}

您也可以使属性可编辑,但如果有任何绑定需要更新,您需要implementINPC

然后新集合的类型应该是ObservableCollection&lt;HotkeyViewModel&gt;,并且模板有两个绑定:

<DataTemplate>
    <Label Content="{Binding DisplayString}">
        <Label.Background>
            <SolidColorBrush Color="{Binding Color}" />
        </Label.Background>
    </Label>
</DataTemplate>

(您也可以将属性设为Brush 并直接绑定到Background

【讨论】:

  • 换句话说,您是在告诉我使用 ListBoxItem 而不是字符串? :p
  • @Eyal-Shilony:实际上这是一个的想法。我的意思是你创建了一个新类,它有两个属性,别动,我会编辑我的答案。
  • @Eyal-Shilony:添加示例。
  • @Eyal-Shilony:是的,模型甚至视图模型中都不应该有任何 UI 元素或 UI 相关的类。如果您有多个属性,则新的 ViewModel 合理的。
  • @Eyal-Shilony:嗯,它不是一个完全合适的 ViewModel,模型有些缺失,如果你有一个,当然可以插入。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 2012-12-24
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
相关资源
最近更新 更多