Передача объекта класса в качестве параметра другому классу не работает - PullRequest
0 голосов
/ 15 апреля 2020

Я новичок в WPF mvvm, и я не могу понять, почему объект, который я передаю другому классу в качестве параметра, является нулевым, но при отображении в виде текстового поля имеет значение. Проще понять, что я имею в виду под кодом.

class TrainAIViewModel : Screen
    {
        public BindableCollection<Digit> Digits { get; set; }
        public TrainAIViewModel(BindableCollection<Digit> digits)
        {
            Digits = digits;
        }
        private Digit _selectedDigit;

        public Digit SelectedDigit
        {
            get { return _selectedDigit; }
            set 
            {
                _selectedDigit = value;
                NotifyOfPropertyChange(() => SelectedDigit);
            }
        }
        private ICommand _savePatternCommand;

        public ICommand SavePatternCommand
        {
            get
            {
                if (_savePatternCommand == null)
                    _savePatternCommand = new SavePattern(Digits, SelectedDigit);
                return _savePatternCommand;
            }
            set { _savePatternCommand = value; }
        }
    }
class SavePattern : ICommand
        {
            #region ICommand Members  
            public BindableCollection<Digit> Digits { get; set; }
            private Digit selectedDigit;
            public SavePattern(BindableCollection<Digit> digits, Digit _selectedDigit)
            {
                Digits = digits;
                selectedDigit = _selectedDigit;
            }
            public bool CanExecute(object parameter)
            {
                return true;
            }
            public event EventHandler CanExecuteChanged
            {
                add { CommandManager.RequerySuggested += value; }
                remove { CommandManager.RequerySuggested -= value; }
            }

            public void Execute(object parameter)
            {
                if(selectedDigit!=null)MessageBox.Show(selectedDigit.Name);//this is the problem
                //selectedDigit doesnt exist for some reason. I need to get value currently selected in combobox and can't see why it doesnt work
                MessageBox.Show(Digits.Count.ToString());//this works
            }
            #endregion

        }

Итак, переданный BindableCollection работает, и у него есть количество объектов в классе viewmodel. Тем более я не понимаю, почему selectedDi git имеет значение null, тем более что текстовое поле, отображающее его значение, работает.

ComboBox Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="2"
                  Margin="0,20,0,0" SelectedItem="{Binding SelectedDigit}"
                  x:Name="Digits">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Name="DigitName" Text="{Binding Name}"
                               />
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>

        <TextBlock Grid.Row="5" Grid.Column="1" x:Name="SelectedDigit_Name"/>
//this shows the value in the combobox. Did this to test if my variable selectedDigit actually has the value of currently selected combobox item

1 Ответ

0 голосов
/ 15 апреля 2020

В вашем установщике SelectedDigit вы должны обновить SavePatternCommand.selectedDigit.

Либо сделайте доступ к field из-за пределов класса, либо вы можете вызвать новую инициализацию.

  1. Сделать его доступным

    class SavePattern : ICommand
    {
        public BindableCollection<Digit> Digits { get; set; }
        public Digit SelectedDigit { get; set; }
    }
    
    public Digit SelectedDigit
    {
        get { return _selectedDigit; }
        set 
        {
            _selectedDigit = value;
            NotifyOfPropertyChange(() => SelectedDigit);
    
            SavePatternCommand.SelectedDigit = value;
        }
    }
    
  2. Принудительная новая инициализация

    public Digit SelectedDigit
    {
        get { return _selectedDigit; }
        set 
        {
            _selectedDigit = value;
            NotifyOfPropertyChange(() => SelectedDigit);
    
            _savePatternCommand = null; //setting the field to null, will "activate" the initialization of the command
            NotifyOfPropertyChange(() => SavePatternCommand); //notify a change done to the command
        }
    }
    

Но было бы лучше, если бы вы команда вообще не использовалась, как эта, но вместо этого использовала CommandParameter.

Вы не показывали ту часть в вашем XAML, где вы на самом деле используете SavePatternCommand, но я предполагаю Вы используете его в Button, это может выглядеть так:

<Button Command="{Binding SavePatternCommand}" CommandParameter="{Binding SelectedDigit}" />

CommandParameter теперь будет автоматически использоваться Command.

И вашим Execute Метод должен выглядеть следующим образом:

public void Execute(object parameter)
{
    //the argument `parameter` will have the `CommandParameter` that gets specified in the `XAML`

    //cast the object to Digit
    var parameterAsDigit = parameter as Digit;
    if (parameterAsDigit == null)
        return;


}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...