使用 RelayCommand 重置 ToggleButton?
Resetting a ToggleButton with a RelayCommand?
WPF C#
下面的代码正确地绘制了一个 ToggleButton B10,当从用户界面(自定义控件 RingButtons2)单击时 会闪烁 并正确执行关联的中继命令 NewRecordingCmd,在录音机中。如果再次单击它,它将正确地停止闪烁。一切顺利。
如何通过 RingButtons2 控件从 AudioRecorder 中的代码将 B10 ToggleButton 的状态更改回未单击--非闪烁状态?换句话说,当存在中间 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));
然后从用户界面使用 RingButtons2 自定义控件 Xaml 作为:
<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;
}
}
你不清楚 post 你的 ViewModel 是什么样子,但一般来说,如果你使用 MVVM 模式,in/from viemodel 你不能强制视图层做某事(改变单选按钮的状态)但只提供信息和视图(如果需要)可以使用此信息(通过绑定),所以可以说允许受到影响。
命令是一个动作,在某些事件上执行,例如Click
,因此您无法将操作绑定到描述状态 IsChecked
.
的 属性
因此,要影响视图,您只需要在 ViewModel 中提供 属性,比如 IsRecording
,您 can/should 将其绑定到单选按钮 [=15] 的 IsChecked
属性=].交替 IsRecording
您将影响(set/reset 单选按钮)视图。
绑定到 IsRecording
您可以在 Xaml 中执行(在您的 post 中没有 PART_Button10
的 XAML 定义)或在代码隐藏,例如在 OnApplyTemplate()
中:
BindingOperations.SetBinding(_B10, RadioButton.IsCheckedProperty, new Binding("IsRecording"));
正如我已经说过的 - 问题是所有控件的 DataContext 是什么。
我最终会在用户控件中创建一个依赖项 属性 而不是命令 B10Cmd
,而是一个 bool IsRecording
并在 viewmodel 中将其与相同的 bool 属性 绑定并在 setter.
中录制所有内容
WPF C#
下面的代码正确地绘制了一个 ToggleButton B10,当从用户界面(自定义控件 RingButtons2)单击时 会闪烁 并正确执行关联的中继命令 NewRecordingCmd,在录音机中。如果再次单击它,它将正确地停止闪烁。一切顺利。
如何通过 RingButtons2 控件从 AudioRecorder 中的代码将 B10 ToggleButton 的状态更改回未单击--非闪烁状态?换句话说,当存在中间 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));
然后从用户界面使用 RingButtons2 自定义控件 Xaml 作为:
<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;
}
}
你不清楚 post 你的 ViewModel 是什么样子,但一般来说,如果你使用 MVVM 模式,in/from viemodel 你不能强制视图层做某事(改变单选按钮的状态)但只提供信息和视图(如果需要)可以使用此信息(通过绑定),所以可以说允许受到影响。
命令是一个动作,在某些事件上执行,例如Click
,因此您无法将操作绑定到描述状态 IsChecked
.
的 属性
因此,要影响视图,您只需要在 ViewModel 中提供 属性,比如 IsRecording
,您 can/should 将其绑定到单选按钮 [=15] 的 IsChecked
属性=].交替 IsRecording
您将影响(set/reset 单选按钮)视图。
绑定到 IsRecording
您可以在 Xaml 中执行(在您的 post 中没有 PART_Button10
的 XAML 定义)或在代码隐藏,例如在 OnApplyTemplate()
中:
BindingOperations.SetBinding(_B10, RadioButton.IsCheckedProperty, new Binding("IsRecording"));
正如我已经说过的 - 问题是所有控件的 DataContext 是什么。
我最终会在用户控件中创建一个依赖项 属性 而不是命令 B10Cmd
,而是一个 bool IsRecording
并在 viewmodel 中将其与相同的 bool 属性 绑定并在 setter.