是否可以使用相同的命令进行相对绑定?

时间:2017-11-23 12:49:45

标签: wpf mvvm

我是WPF和MVVM的新手,我有以下问题

  1. 我有3个按钮
  2. 当我点击一个按钮时,它会获得CommandParameter,例如:0,1
  3. 命令SetBackGroundCommandParameter拆分为提取行和列
  4. 现在,我尝试使用具有条件的IsSelectedBackground来设置Background
  5. 问题是......当我点击所有按钮时,它们设置了黄色Background,但我只需要具有正确条件的按钮,所以..
  6. 我是否需要为每个按钮设置不同的背景,或者是否存在其他方式?

    谁说..如果这个条件“参数”将背景设置为黄色,其他 - 则不是。

    图片

    image

    视图模型

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Windows.Input;
    using Testing00.Commands;
    
    namespace Testing00.ViewModels
    {
        public class ViewModel : INotifyPropertyChanged
        {
    
            public ICommand SetBackGroundCommand { get; set; }
            bool LeftSelected { get; set; }
            bool RightSelected { get; set; }
    
            #region Methods
            int row;
            public int Row
            {
                get { return row; }
                set { row = value; }
            }
    
            int column;
            public int Column
            {
                get { return column; }
                set { column = value; }
            }
    
            public bool IsSelected
            {
                get
                {
                    if (row == 0 && column == 0)
                    {
                        return false;
                    }
                    else
                    {
    
                        return true;
                    }
                }
                set
                {
                    OnPropertyChanged("IsSelected");
                    OnPropertyChanged("Background");
                }
            }
    
            public string Background
            {
                get
                {
                    return IsSelected ? "Yellow" : "Transparent";
                }
            }
    
            #endregion
    
    
            #region Constructor
    
            public ViewModel()
            {
                SetBackGroundCommand = new RelayCommand(SetBackGround, param => true);
            }
    
            #endregion
    
            private void SetBackGround(object obj)
            {
                string[] commandParametters = obj.ToString().Split(',');
                Row = Convert.ToInt32(commandParametters[0]);
                Column = Convert.ToInt32(commandParametters[1]);
                OnPropertyChanged("IsSelected");
                OnPropertyChanged("BackGround");
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
            public void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
        }
    }
    

    MainWindows

    <Window x:Class="Testing00.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:TEST="clr-namespace:Testing00.ViewModels"
            xmlns:local="clr-namespace:Testing00"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <TEST:ViewModel x:Key="testVM"></TEST:ViewModel>
        </Window.Resources>
        <Grid>
            <Button Content="0,0" HorizontalAlignment="Left" Margin="84,109,0,0" VerticalAlignment="Top" Width="79" Height="81"    CommandParameter="0,0" Command="{Binding SetBackGroundCommand, Source={StaticResource testVM}}" Background="{Binding Background, Mode=OneWay, Source={StaticResource testVM}}"    />
            <Button Content="0,1" HorizontalAlignment="Left" Margin="208,109,0,0" VerticalAlignment="Top" Width="79" Height="81" CommandParameter="0,1" Command="{Binding SetBackGroundCommand, Source={StaticResource testVM}}"  Background="{Binding Background, Mode=OneWay, Source={StaticResource testVM}}" />
            <Button Content="0,2" HorizontalAlignment="Left" Margin="341,109,0,0" VerticalAlignment="Top" Width="79" Height="81"  CommandParameter="0,2" Command="{Binding SetBackGroundCommand, Source={StaticResource testVM}}"  Background="{Binding Background, Mode=OneWay, Source={StaticResource testVM}}" />
        </Grid>
    </Window>
    

    RelayCommand

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Input;
    
    namespace Testing00.Commands
    {
        public class RelayCommand : ICommand
        {
    
            Action<object> _execute;
            Func<object, bool> _canexecute;
            public RelayCommand(Action<object> execute, Func<object, bool> canexecute)
            {
                _execute = execute;
                _canexecute = canexecute;
    
            }
            public bool CanExecute(object parameter)
            {
                if (_canexecute != null)
                {
                    return _canexecute(parameter);
                }
                else
                {
                    return false;
                }
            }
    
            public event EventHandler CanExecuteChanged
            {
                add { CommandManager.RequerySuggested += value; }
                remove { CommandManager.RequerySuggested -= value; }
            }
    
            public void Execute(object parameter)
            {
                _execute(parameter);
            }
        }
    }
    

1 个答案:

答案 0 :(得分:0)

粗略地说,并且只显示很少的代码(如果你查找ItemsControl,你可以找到更多代码),你可以像 grek40 那样说。

您的按钮将是一个usercontrol(ucMyButton),具有自己的viewmodel及其属性。

在主视图中,您将添加ItemControl,它将包含一组按钮(ObservableCollection<MyButtonViewModel> MyButtons { ..... }

然后每个MyButtonViewModel将是一个单独的按钮,具有自己的Background属性,因此每个按钮可以单独设置

<ItemsControl x:Name="itmWrapPanel" 
            ItemsSource="{Binding MyButtons, UpdateSourceTrigger=PropertyChanged}"  

            ScrollViewer.CanContentScroll="True"
            ScrollViewer.VerticalScrollBarVisibility="Auto"
            ScrollViewer.HorizontalScrollBarVisibility="Auto"
            >
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"  
                    Background="White" 
                    AllowDrop="True" 
                    Width="{Binding ActualWidth, ElementName=itmWrapPanel}" 
                    Height="{Binding ActualHeight, ElementName=itmWrapPanel}"  />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate  >
            <local:ucMyButton  />

        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>