可观察收集命令绑定MVVM wpf

mwg9r5ms  于 2023-06-24  发布在  其他
关注(0)|答案(1)|浏览(134)

我的代码有问题。当我将一个命令绑定到xaml中的单个元素时,我的ShowCommand就可以工作了。但是当我试图设置一个itemscontrol与observable收集它不t work. I我在mvvm的wpf新手,所以请不要打我!
这种变体的工作原理是:

<StackPanel>
   <Grid Background="Black">
      <Grid.ColumnDefinitions>
         <ColumnDefinition/>
         <ColumnDefinition/>
      </Grid.ColumnDefinitions>
      <Border BorderBrush="Blue" BorderThickness="2" Grid.ColumnSpan="2"/>
         <StackPanel>
            <Button Grid.Column="0" VerticalAlignment="Center" Content="What is Netflix?" FontSize="30" Foreground="White" Command="{Binding ShowPanelCommand}">
            </Button>
            <TextBlock Grid.Column="1" HorizontalAlignment="Right" Text="+" FontSize="60" Foreground="White">
            </TextBlock>
            <StackPanel Margin="0 5 0 0" Visibility="{Binding IsPanelVisible, Converter={StaticResource BooleanToVisibility}}">
               <TextBlock Foreground="White" FontSize="20" Text="{Binding MyTextMain, UpdateSourceTrigger=PropertyChanged}"> 
               </TextBlock>
               <TextBlock Margin="0 20 0 0" Foreground="White" FontSize="20">Text2</TextBlock>
            </StackPanel>
         </StackPanel>

我想要达到的

<Window.Resources>
                <BooleanToVisibilityConverter x:Key="BooleanToVisibility"/>
            <Window.Resources/>
          **<ItemsControl ItemsSource="{Binding Path=MM1}">**
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                               <Grid Background="Black">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <Border BorderBrush="Blue" BorderThickness="2" Grid.ColumnSpan="2"/>
                        <StackPanel>
                            <Button Grid.Column="0" VerticalAlignment="Center" Content="What is 
                                              Netflix?"
                                           FontSize="30" Foreground="White" Command="{Binding 
                                    ShowPanelCommand}">

                            </Button>
                            <TextBlock Grid.Column="1" HorizontalAlignment="Right" Text="+"
                                           FontSize="60" Foreground="White">
                            </TextBlock>
                            <StackPanel Margin="0 5 0 0" Visibility="{Binding IsPanelVisible,   
                           Converter={StaticResource BooleanToVisibility}}">
                                <TextBlock Foreground="White" FontSize="20" Text="{Binding 
                            MyTextMain, UpdateSourceTrigger=PropertyChanged}"></TextBlock>
                                <TextBlock Margin="0 20 0 0" Foreground="White" FontSize="20">
                                        Text2
                                </TextBlock>
                            </StackPanel>
                        </StackPanel>

                                </Grid>
                            </StackPanel>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>

ViewModel:ViewModelBase

private ICommand myCommand;
        public ObservableCollection<MMViewModel> mm1;
        
        private bool _isPanelVisible;
        
        private ICommand _showPanelCommand;
        
        public bool IsPanelVisible
        {
            get { return _isPanelVisible; }
            set
            {
                _isPanelVisible = value;
                OnPropertyChanged(nameof(IsPanelVisible));
            }
        }
        public void ShowPanel()
        {
            IsPanelVisible = true;
        }
        public ICommand ShowPanelCommand
        {
            get
            {
                if (_showPanelCommand == null)
                {
                    _showPanelCommand = new MyCommand(p => ShowPanel());
                }
                return _showPanelCommand;
            }
        }

        public ObservableCollection<MMViewModel> MM1
        {
            get { return mm1; }
            set
            {
                mm1 = value;
                OnPropertyChanged(nameof(MM1));
            }
        }

        
        public MyVievModel()
        {
            IsPanelVisible = false;
                       
            MM1 = new ObservableCollection<MMViewModel>();
            MM1.Add(new MMViewModel
            {
                MyTextMain = "Text1"
            }) ;
        }
      }

MyCommand

public class MyCommand: ICommand
    {
        private readonly Action<object> _execute;
        private readonly Predicate<object> _canExecute;
        public MyCommand(Action<object> execute, Predicate<object> canExecute = null)
        {
            if (execute == null) throw new ArgumentNullException(nameof(execute));
            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute == null || _canExecute(parameter);
        }

        public event EventHandler? CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            _execute(parameter ?? "N</A>");
        }
    }

抽象类

public abstract class ViewModelBase : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler? PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }

型号:

class MyModel
    {
        
        public string? mainText;
        
    }

视图模型2

public class MMViewModel: ViewModelBase
    {
        MyModel M = new MyModel();
         

        public string? MyTextMain
        {
            get
            {
                return M.mainText;
            }
            set
            {
                M.mainText = value;
                OnPropertyChanged(nameof(MyTextMain));
            }
        }

    }

感谢您的评论!

2sbarzqh

2sbarzqh1#

当您执行此操作时:

<ItemsControl ItemsSource="{Binding Path=MM1}">

ItemsControl中的每个绑定都将使用MM1中的元素作为每次迭代的DataContext。所以它找不到ShowPanelCommand。您可以做的是命名根控件,并在创建不属于MM1的绑定时使用它。
就像这样:

<Window ...
        ...
        x:Name="MainWindow"

然后:

<ItemsControl ItemsSource="{Binding Path=MM1}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        ...
                        ...
                        <Button Grid.Column="0" VerticalAlignment="Center" Content="What is 
                                          Netflix?"
                                       FontSize="30" Foreground="White" Command="{Binding 
                                DataContext.ShowPanelCommand, ElementName=MainWindow}">

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

希望这有帮助!

相关问题