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;
}
}
答案 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属性绑定,并在设置器中记录所有内容。