Сброс ToggleButton с помощью RelayCommand? - PullRequest
0 голосов
/ 02 января 2019

WPF C #

Приведенный ниже код правильно рисует ToggleButton B10, который будет мигать при щелчке по интерфейсу пользователя (пользовательский элемент управления RingButtons2) и правильно выполнять соответствующую команду реле,NewRecordingCmd, в AudioRecorder.Если щелкнуть снова, он перестанет мигать.Все хорошо.

Как можно изменить состояние ToggleButton B10 обратно в состояние без щелчка - не мигает из кода в AudioRecorder через элемент управления RingButtons2?Другими словами, как я могу сбросить B10 ToggleButton в исходное состояние из кода в AudioRecorder, если есть промежуточный элемент управления RingButtons2?

Это не работает с AudioRecorder:

 NewRecordingCmd.Execute(false);

Заранее благодарим за любую помощь или предложения.

ToggleButton в основном определяется в моем пользовательском элементе управления (Generic.xaml) как:

<Style x:Key="BaseButtonStyle" TargetType="{x:Type ToggleButton}">
        <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Blue"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Grid>

                        <Path x:Name="path1" Data="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Data)}" 
                              Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Fill)}" 
                              Stroke="Black"/>

                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" 
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
                        </Trigger>
                        <Trigger Property="IsChecked" Value="true">
                            <Trigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
                            </Trigger.EnterActions>
                            <Trigger.ExitActions>
                                <BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
                            </Trigger.ExitActions>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Тогда, в OnApplyTemplate ():

 _B10 = GetTemplateChild("PART_Button10") as ToggleButton;
 _B10.Command = B10Cmd;

, где в пользовательском элементе управления B10Cmd:

 public ICommand B10Cmd
        {
            get { return (ICommand)GetValue(B10CmdProperty); }
            set { SetValue(B10CmdProperty, value); }
        }

        // Using a DependencyProperty as the backing store for B10Cmd.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty B10CmdProperty =
            DependencyProperty.Register("B10Cmd", typeof(ICommand), typeof(RingButtons2), new UIPropertyMetadata(null));

Пользовательский элемент управления RingButtons2 затем используется из пользовательского интерфейса Xaml как:

<w:RingButtons2
                B10Cmd ="{Binding NewRecordingCmd, ElementName=AudioRecorder}"               
                />

NewRecordingCmd в AudioRecorder (также пользовательский элемент управления) определяется как:

 public RelayCommand<bool> NewRecordingCmd
        {
            get
            {
                if (_newRecordingCmd == null)
                {
                    _newRecordingCmd = new RelayCommand<bool>(
                        (isChecked) =>
                        {
                            if (isChecked)
                            {
                                ActiveAudioFile = Path.Combine(Path.GetTempPath(), Guid.NewGuid() + ".wav");
                                AudioFileState = AudioFileStateEnum.New;   // File has not been created  yet.
                                FileLoaded = false;
                            }

                        }, (isChecked) => AudioRecorderState == AudioRecorderStateEnum.Monitoring);
                }
                return _newRecordingCmd;
            }
        }

1 Ответ

0 голосов
/ 02 января 2019

Из вашего поста не ясно, как выглядит ваша ViewModel, но в целом, если вы используете шаблон MVVM, в / из viemodel вы не можете принудительно заставить слой представления что-либо делать (изменить состояние переключателя), но только предоставлять информацию и просматривать (если он хочет) может использовать эту информацию (через связывание), так сказать, позволяет повлиять.
Команда - это действие, которое выполняется над некоторым событием, например, Click, поэтому вы не можете привязать действие к свойству, которое описывает состояние IsChecked.
Таким образом, чтобы повлиять на представление, вам нужно просто указать свойство, скажем IsRecording, в ViewModel, которое вы можете / должны связать с свойством IsChecked переключателя PART_Button10. Изменяя IsRecording, вы влияете (устанавливаете / сбрасываете радио-кнопку) вид.

Привязка к IsRecording вы можете сделать либо в Xaml (в вашем посте нет определения XAML для PART_Button10), либо в коде, например, например. в OnApplyTemplate():

BindingOperations.SetBinding(_B10, RadioButton.IsCheckedProperty, new Binding("IsRecording"));

Как я уже сказал - вопрос в том, что такое DataContext всех элементов управления.

Я бы в конечном итоге сделал в пользовательском элементе управления свойством зависимости не команду B10Cmd, а bool IsRecording, и связал бы его с тем же свойством bool в viewmodel и сделал бы все с записью в установщике.

...