从WPF中的View和View Model访问属性
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从WPF中的View和View Model访问属性相关的知识,希望对你有一定的参考价值。
我正在使用MVVM格式在WPF和Prism中编写3D建模程序。
我正在使用画布用网格线显示不同的视图(顶部,正面,侧面)。我希望用户能够调整行之间的间距,并且我有一个包含值的TextBox,该值绑定到视图模型中的属性。这部分工作正常。
但是,要使用用户的间距绘制网格线,我需要从视图中访问该属性,在该视图中绘制线条(在MainWindow.xaml.cs中)。不过,我仍然需要它存在于视图模型中,因为某些功能可以工作(比如对齐网格)。
我预计会有很多属性需要来回反复,因为UI和功能将在这样的程序中紧密协作。
我过去解决这个问题的方法是首先在UI中创建一个不可见的标签。然后我使用函数动态设置标签的绑定并从标签中获取值。
public int TempIntBind(string bind)
{
DummyLabel.SetBinding(Label.ContentProperty, new Binding(bind));
int newInt;
if (DummyLabel.Content != null && int.TryParse(DummyLabel.Content.ToString(), out newInt))
{
return newInt;
}
else
{
return -1;
}
}
这有效,但它似乎相当hacky并且也绕过了MVVM模式。
有没有更好的方法来实现这个结果?
以来:
this.DataContext = new View_Model ();
我希望我能说出类似的话:
x = this.DataContext.gridsize;
但显然这不是那么有效。我认为,太像javascript了。
以下是我的主窗口xaml的相关位:
<Window x:Class="Brick.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Brick"
mc:Ignorable="d"
Title="Brick" Width="800" Height="600">
<WrapPanel Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Margin="5">
<Label>Grid Size</Label>
<TextBox Width="50" Height="20" Text="{Binding Path=grid_size, UpdateSourceTrigger=PropertyChanged}" />
</WrapPanel>
<Canvas Grid.Column="1" Grid.Row="2" x:Name="top_view" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,5,5" Background="Black"></Canvas>
</Grid>
</Window>
风景:
namespace Brick
{
public partial class MainWindow : Window
{
public MainWindow ()
{
InitializeComponent ();
this.DataContext = new View_Model ();
draw_grid_lines ();
}
void draw_grid_lines ()
{
int spaces = grid_size; // <-- Right here is the problem spot
}
}
}
和视图模型:
namespace Brick
{
class View_Model : Prism.Mvvm.BindableBase
{
public event PropertyChangedEventHandler property_changed_event;
private int grid_size_private;
public int grid_size
{
get {return grid_size_private;}
set
{
if (grid_size_private != value)
{
grid_size_private = value;
RaisePropertyChanged ("grid_size");
}
}
}
public View_Model ()
{
grid_size = 8;
}
}
}
答案
你是否尝试在后面的代码中将DataContext转换为View_Model?
namespace Brick
{
public partial class MainWindow : Window
{
public MainWindow ()
{
InitializeComponent ();
this.DataContext = new View_Model ();
draw_grid_lines ();
}
void draw_grid_lines ()
{
var vm = (View_Model)this.DataContext;
int spaces = vm.grid_size; // <-- Right here is the problem spot
}
}
}
另一答案
您可以将属性分配给DataContext
,只需通过它访问成员:
namespace WpfApp1
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
Model = new Model();
DataContext = Model;
}
private Model Model { get; }
private void Whatever()
{
var value = Model.Value;
}
}
internal class Model
{
public int Value { get; set; }
}
}
对于您遇到的语法问题,您会做到:
var x = ((Model) DataContext).Value;
以上是关于从WPF中的View和View Model访问属性的主要内容,如果未能解决你的问题,请参考以下文章
2022-03-17 WPF面试题 如何理解MVVM中的 View 和 ViewModel?