从WPF中的View和View Model访问属性

时间:2018-03-05 19:16:52

标签: c# wpf mvvm

我正在使用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-y。

以下是我的主窗口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
      }
    }
  }

和View-Model:

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;
      }
    }
  }

2 个答案:

答案 0 :(得分:1)

您是否尝试在后面的代码中将 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
      }
   }
}

答案 1 :(得分:0)

您可以将属性分配给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;