【问题标题】:Accessing a property from both the View and the View Model in WPF从 WPF 中的视图和视图模型访问属性
【发布时间】:2018-03-06 03:41:01
【问题描述】:

我正在使用 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;
      }
    }
  }

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案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
          }
       }
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我认为您在“私有模型模型”中有错字。也许您的意思是“私有模型模型”。前者会产生双重定义错误。我也不确定来自 View_Model 的信息是如何进入您的示例中的 Model 的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多