使用RelayCommand重置ToggleButton?

时间:2019-01-02 03:25:49

标签: wpf xaml custom-controls togglebutton

WPF C#

下面的代码正确绘制了一个ToggleButton B10,当从用户界面(自定义控件RingButtons2)单击该时,它会闪烁,并在AudioRecorder中正确执行关联的中继命令NewRecordingCmd。如果再次单击它,它将正确停止闪烁。一切都很好。

如何通过RingButtons2控件将B10 ToggleButton的状态从AudioRecorder中的代码更改回未单击的非闪烁状态?换句话说,当存在中间的RingButtons2控件时,如何从AudioRecorder中的代码将B10 ToggleButton重置为其初始状态?

这在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));

然后在用户界面Xaml中将RingButtons2 cusom控件用作:

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

AudioRecorder(也是自定义控件)中的NewRecordingCmd定义为:

 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 :(得分:1)

目前尚不清楚您的ViewModel是什么样子,但是通常来说,如果您使用MVVM模式,则在viemodel中/从viemodel中,您不能强迫视图层执行某些操作(更改单选按钮的状态),而只能提供信息,并且视图(如果需要)可以使用此信息(通过绑定),也就是说可以受到影响。
命令是一种动作,在某些事件(例如Click,因此您无法将操作绑定到描述状态IsChecked的属性。
因此,要影响视图,您只需在ViewModel中提供一个属性,例如IsRecording,您可以/应该将其绑定到单选按钮IsChecked的{​​{1}}属性。交替使用PART_Button10将影响(设置/重置单选按钮)视图。

IsRecording的绑定可以在Xaml中完成(帖子中没有IsRecording的XAML定义),也可以在例如在PART_Button10中:

OnApplyTemplate()

正如我已经说过的-问题是所有控件的DataContext是什么。

我最终将在用户控件中使依赖项属性不是命令BindingOperations.SetBinding(_B10, RadioButton.IsCheckedProperty, new Binding("IsRecording")); ,而是布尔B10Cmd,并将其与viewmodel中的相同bool属性绑定,并在设置器中记录所有内容。