使用 Prism 6 从 Wpf 框架绑定 height/width
Binding height/width from a Wpf Frame with Prism 6
我的 ViewMain.xaml 中有一个框架,我需要从中读取 height/width。在 ViewModel 中,我有 2 个棱镜属性和一个应该通过 ObservesProperty 调用的命令。该命令使用 height/width 进行一些计算。我尝试将 height/width 与所有模式(TwoWay 等)绑定。
我有的是:
ViewMain.xaml:
<UserControl x:Class="WpfApplication3.Views.ViewMain"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="300" d:DesignWidth="300"
>
<Grid>
...
<Frame Content="{Binding MainGrid}" Margin="0,30,0,0" Height="{Binding GridHeight, Mode=OneWayToSource}" Width="{Binding GridHeight, Mode=OneWayToSource}"/>
</Grid>
并且在 ViewMainViewModel.cs 中:
...
public class ViewMainViewModel : BindableBase
{
public DelegateCommand SizeUpdateCommand { get; set; }
private Grid _mainGrid;
public Grid MainGrid
{
get { return _mainGrid; }
set { SetProperty(ref _mainGrid, value); }
}
private double _gridHeight = 300;
public double GridHeight
{
get { return _gridHeight; }
set { SetProperty(ref _gridHeight, value); }
}
private double _gridWidth = 420;
public double GridWidth
{
get { return _gridWidth; }
set { SetProperty(ref _gridWidth, value); }
}
public ViewMainViewModel()
{
Grid newGrid = new Grid();
MainGrid = newGrid;
SizeUpdateCommand = new DelegateCommand(Execute, CanExecute).ObservesProperty(() => GridHeight).ObservesProperty(() => GridWidth);
}
private void Execute()
{
SomeMethod();
}
private bool CanExecute()
{
return true;
}
...
是否有人发现问题或我必须更改什么?
这不是 Prism 问题。这与尝试绑定到框架的 height/width 在 WPF 中的工作方式有关。如果您只想通过命令跟踪 ViewModel 中框架的大小变化,那么我会推荐一种完全不同的方法。只需使用 InvokeCommandAction:
<Frame>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SizeChanged">
<prism:InvokeCommandAction Command="{Binding SizeUpdateCommand}" TriggerParameterPath="NewSize" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Frame>
然后将您的 DelegateCommand 更改为:
public DelegateCommand<object> SizeUpdateCommand { get; set; }
private void Execute(object size)
{
var newSize = (Size)size;
}
private bool CanExecute(object size)
{
return true;
}
现在,只要帧大小发生变化,您的 VM 就会知道。
P.S。永远不要在您的 VM 中创建或引用 UI 对象。甚至不是 DependencyObject。摆脱您的 MainGrid 属性 和任何对 Grid 的引用。
我的 ViewMain.xaml 中有一个框架,我需要从中读取 height/width。在 ViewModel 中,我有 2 个棱镜属性和一个应该通过 ObservesProperty 调用的命令。该命令使用 height/width 进行一些计算。我尝试将 height/width 与所有模式(TwoWay 等)绑定。
我有的是: ViewMain.xaml:
<UserControl x:Class="WpfApplication3.Views.ViewMain"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
d:DesignHeight="300" d:DesignWidth="300"
>
<Grid>
...
<Frame Content="{Binding MainGrid}" Margin="0,30,0,0" Height="{Binding GridHeight, Mode=OneWayToSource}" Width="{Binding GridHeight, Mode=OneWayToSource}"/>
</Grid>
并且在 ViewMainViewModel.cs 中:
...
public class ViewMainViewModel : BindableBase
{
public DelegateCommand SizeUpdateCommand { get; set; }
private Grid _mainGrid;
public Grid MainGrid
{
get { return _mainGrid; }
set { SetProperty(ref _mainGrid, value); }
}
private double _gridHeight = 300;
public double GridHeight
{
get { return _gridHeight; }
set { SetProperty(ref _gridHeight, value); }
}
private double _gridWidth = 420;
public double GridWidth
{
get { return _gridWidth; }
set { SetProperty(ref _gridWidth, value); }
}
public ViewMainViewModel()
{
Grid newGrid = new Grid();
MainGrid = newGrid;
SizeUpdateCommand = new DelegateCommand(Execute, CanExecute).ObservesProperty(() => GridHeight).ObservesProperty(() => GridWidth);
}
private void Execute()
{
SomeMethod();
}
private bool CanExecute()
{
return true;
}
...
是否有人发现问题或我必须更改什么?
这不是 Prism 问题。这与尝试绑定到框架的 height/width 在 WPF 中的工作方式有关。如果您只想通过命令跟踪 ViewModel 中框架的大小变化,那么我会推荐一种完全不同的方法。只需使用 InvokeCommandAction:
<Frame>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SizeChanged">
<prism:InvokeCommandAction Command="{Binding SizeUpdateCommand}" TriggerParameterPath="NewSize" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Frame>
然后将您的 DelegateCommand 更改为:
public DelegateCommand<object> SizeUpdateCommand { get; set; }
private void Execute(object size)
{
var newSize = (Size)size;
}
private bool CanExecute(object size)
{
return true;
}
现在,只要帧大小发生变化,您的 VM 就会知道。
P.S。永远不要在您的 VM 中创建或引用 UI 对象。甚至不是 DependencyObject。摆脱您的 MainGrid 属性 和任何对 Grid 的引用。