从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访问属性的主要内容,如果未能解决你的问题,请参考以下文章

wpf mvvm下viewmodel中对view进行操作

WPF MVVM 从 VIEW MODEL 获取父级

2022-03-17 WPF面试题 如何理解MVVM中的 View 和 ViewModel?

WPF---MVVM初尝试

WPF 在MVVM模式下怎样在Viewmodel里面控件与view中控件相关联。

MVVM模式解析和在WPF中的实现