簡體   English   中英

為ListBoxItem綁定mouseLeftButtonDown和PropertyChanged(mvvm,wpf)上的背景色

[英]Bind mouseLeftButtonDown for ListBoxItem and background color on PropertyChanged (mvvm, wpf)

抱歉,如果您認為這是另一篇文章的副本,但是我嘗試了所有可能的解決方法,但無法使它起作用。

這個問題有兩個部分,但涉及的是相同的代碼,所以我想我可以在同一線程中提問。

我嘗試使用不帶任何(硬編碼)耦合的mvvm在C#,wpf,vs2015中對系統進行排序。 我需要做兩件事。 首先是觸發一個我需要在ViewModel中捕獲的事件,其次,當文章數超過一定水平時,該文章的listboxitem的背景應該為綠色(否則為白色/灰色)

為此,我使用一個ListBox和一些listBoxItems。

MainWindow.xaml(重要部分)

        <Window x:Class="Sequence_Application_2.GUI.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:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:acb="clr-namespace:AttachedCommandBehavior;assembly=AttachedCommandBehavior"
        mc:Ignorable="d"
        ....
    <Window.DataContext>

<Grid Grid.Column="0" Margin="10">
                <ListBox x:Name="LstViewFlows" SelectedItem="{Binding SelectedFlow.Name}" ItemsSource="{Binding Flows.Keys}" >
                    <ListBox.ItemContainerStyle>
                        <Style TargetType="{x:Type ListBoxItem}" >
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding SelectedFlow.CanDeliver, UpdateSourceTrigger=PropertyChanged}" Value="true" >
                                    <Setter Property="ListBoxItem.Background" Value="DarkGreen" />
                                    <Setter Property="FontWeight" Value="Bold"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ListBox.ItemContainerStyle>
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="MouseLeftButtonDown">
                            <i:InvokeCommandAction Command="{Binding SetSelectedCommand}"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </ListBox>
            </Grid>

問題1)

單擊列表框中的listboxItem時,需要將命令綁定到“ MouseLeftButtonDown”事件。 我嘗試了ACB解決方案,但無法正常工作。 最后,我嘗試了上面的代碼,但是當我單擊某個項目時卻無法觸發它,但是在這些項目下方的列表框的空白部分(不在listboxitem上),它會自動觸發。 猜猜我需要重新整理我的xaml文件或其他內容,但是我嘗試了兩天,但似乎沒有任何效果。

該命令名為“ setSelectedCommand”,並按以下方式實現

internal class SetSelectedFlowCommand : ICommand
{
    private FlowsViewModel _flowsViewModel;

    public SetSelectedFlowCommand(FlowsViewModel flowsViewModel)
    {
        _flowsViewModel = flowsViewModel; 
    }

    /// <summary>
    /// 
    /// </summary>
    public event EventHandler CanExecuteChanged
    {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _flowsViewModel.SetSelectedFlow();
    }
}

就像我說的,如果我單擊ListBoxItem-不會發生任何事情,但是如果我單擊ListBox-會觸發命令(但“選擇”沒有任何內容)

問題2

如您在上面的xaml中所看到的,我嘗試基於存儲在ViewModel字典中的對象中的值.CanDeliver設置ListBoxitem的背景顏色。 變量Flow是字典,而SelectedFlow應該是選定的流。

這是一個訂單系統,CanDeliver是一個變量,它告訴操作員/用戶是否有足夠的產品可以交付給客戶。 如果列表框足夠多,則應為綠色,否則請保持白色/灰色。 你明白我的問題嗎? 我可以這樣嗎? 指字典中的對象? (由對象中的INotifyPropertyChanged觸發)

希望你能幫助我,因為現在我的頭發不再多余;-)

如果只需要獲取selectedItem,則不需要使用事件處理程序。 我為您構建了一個工作示例,以演示如何使用僅綁定(MVVM)來滿足您的問題要求:

C#(ViewModel):

using System;
using System.Collections.Generic;
using System.Windows;
using System.ComponentModel;
using System.Collections.ObjectModel;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MyViewModel mvm = new MyViewModel()
            {
                Flows = new ObservableCollection<Flow>() 
                { 
                    new Flow() { Name = "Flow1" }, 
                    new Flow() { Name = "Flow2" }, 
                    new Flow() { Name = "Flow3" , Amount=1}, 
                    new Flow() { Name = "Flow4" } 
                }
            };
            this.DataContext = mvm;
        }
    }

    public class MyViewModel : ObservableObject
    {
        private Flow _selectedflow;
        public ObservableCollection<Flow> Flows
        {
            get;
            set;
        }

        public Flow SelectedFlow
        {
            get { return _selectedflow; }
            set
            {
                if (value != _selectedflow)
                {
                    _selectedflow = value;
                    RaisePropertyChanged("SelectedFlow");
                }
            }
        }
    }

    public class Flow : ObservableObject
    {
        private string _name;
        private int _amount;
        public string Name
        {
            get { return _name; }
            set
            {
                if (value != _name)
                {
                    _name = value;
                    RaisePropertyChanged("Name");
                }
            }
        }

        public bool CanDeliver
        {
            get
            {
                return Amount > 0;
            }
        }

        public int Amount
        {
            get { return _amount; }
            set
            {
                if (value != _amount)
                {
                    _amount = value;
                    RaisePropertyChanged("Amount");
                    RaisePropertyChanged("CanDeliver");
                }
            }
        }
    }

    public class ObservableObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected void RaisePropertyChanged(String propertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }
    }
}

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="300" Width="350">
    <Grid>
        <StackPanel Orientation="Vertical">
        <ListBox SelectedItem="{Binding SelectedFlow}" ItemsSource="{Binding Flows}" DisplayMemberPath="Name">
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}" >
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding CanDeliver, UpdateSourceTrigger=PropertyChanged}" Value="true" >
                            <Setter Property="Background" Value="DarkGreen" />
                            <Setter Property="FontWeight" Value="Bold"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
        <TextBlock Text="{Binding SelectedFlow.Name}"/>
        </StackPanel>
    </Grid>
</Window>

結果:您可以看到CanDeliver = TrueAmount>0 )的Flow項目具有綠色背景。 TextBlock顯示的是SelectedFlow

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM