我对WPF、XAML和数据绑定相对陌生。我有一个视图(Window)和一个视图模型。
我已经尝试实现MVVM模式,这意味着视图和视图模型都没有相互引用。所有数据交换都通过数据绑定进行。
到目前为止还不错,但现在我遇到了一个我找不到解决方案的问题。
在我的视图中,我有一个绑定到命令的"开始"按钮。
<Button Command="{Binding NextCommand}" Content="Next">
NextCommand属于ActionCommand : ICommand
类型
在我的例子中,NextCommand只是在视图模型中调用一个私有方法。
到目前为止,我找不到解决方案的问题如下:
如何关闭视图模型末尾的窗口NextCommandAction方法?
private void NextCommandAction(object o)
{
...
...
// close the window
}
由于我没有对视图的引用,我不能只设置DialogResult = true;
到目前为止,我找到的唯一可行的解决方案是向视图中添加一个隐藏的单选按钮,并将其值绑定到属性CloseView,然后在xaml.cs文件中创建一个方法CloseView,该文件绑定到隐藏单选按钮的Checked事件。在该方法中,我将DialogResult设置为true;
虽然这很有效,但我觉得必须有一个比在视图中添加隐藏元素更好的解决方案!
您可以将窗口引用作为CommandParameter传递给Close命令,并在窗口上执行任何需要的操作。
<Button Content="Close" Command="{Binding Path=CloseCommand}"
CommandParameter="{Binding ElementName=Window}"/>
private void CloseCommand(object sender)
{
Window wnd = sender as Window;
wnd.Close();
}
CommandParameter="{Binding ElementName=Window}"
假设XAML中有一个名为"Window"的元素。例如,您的Window标签需要Name="Window"
当我在谷歌上搜索DialogResult
是否是依赖属性(它不是:-))时,首先出现了这个问题
将依赖属性添加到您的窗口:
public static readonly DependencyProperty InteractionResultProperty =
DependencyProperty.Register(
nameof(InteractionResult),
typeof(Boolean?),
typeof(MyWpfWindow1),
new FrameworkPropertyMetadata(default(Boolean?),
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnInteractionResultChanged));
public Boolean? InteractionResult
{
get => (Boolean?) GetValue(InteractionResultProperty);
set => SetValue(InteractionResultProperty, value);
}
private static void OnInteractionResultChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((MyWpfWindow1) d).DialogResult = e.NewValue as Boolean?;
}
我将我的属性命名为InteractionResult,尽管一个好的名称也会起作用。
在xaml中您可以将其与样式绑定
<Window.Style>
<Style TargetType="{x:Type z:MyWpfWindow1}">
<Setter Property="InteractionResult"
Value="{Binding UpdateResult}" />
</Style>
</Window.Style>
UpdateResult是我的视图模型中的属性。
private Boolean? _updateResult;
public Boolean? UpdateResult
{
get => _updateResult;
set => SetValue(ref _updateResult, value);
}
SetValue方法是通常的通知属性
protected virtual Boolean SetValue<T>(ref T field, T value,
[CallerMemberName]String propertyName = null)
{
if (Equals(field, value))
return false;
field = value;
RaisePropertyChanged(propertyName);
return true;
}
属性以通常的方式设置
<Button Content="Cancel"
Command="{Binding CancelCommand}" />
ICommand CancelCommand { get; }
private void OnCancel()
{
UpdateResult = false;
}
免责声明:在我的电脑上工作。
受到Chandrashekhar Joshi答案的启发(但不使用元素名称):
在按钮中定义命令参数:
<Button
Command="{Binding CloseCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}"
Content="Close" />
定义命令(和实施):
CloseCommand = new DelegateCommand<Window>((w) => w.DialogResult = true);