从用户控件访问父窗口的网格

时间:2017-06-08 18:28:49

标签: c# wpf mvvm

在我的MainWindow VM中,我打开了来自我的UserControls的视图。 Usercontrol1是在Xaml中创建的View的名称。 在我的MainWindow的ViewModel中:

/**
 * Automatically sorts the 1st column (not the header row) Ascending.
 */
function onEdit(event){
  var sheet = event.source.getActiveSheet();
  var editedCell = sheet.getActiveCell();

  var columnToSortBy = 4;
  var tableRange = "A2:T99"; // What to sort.

  if(editedCell.getColumn() == columnToSortBy){   
    var range = sheet.getRange(tableRange);
    range.sort( { column : columnToSortBy, ascending: false } );
  }
  onEdit2();
}


function onEdit2(event){
   var timezone = "UTC-5";
  var timestamp_format = "mm-dd-yyyy'Time:' hh:mm:ss";
  var updateColName = "Parent Sign-Out";
  var timeStampColName = "Timestampt";
  var sheet = event.source.getSheetByName('Sheet1, Sheet2'); //Name of the sheet where you want to run this script.


  var actRng = event.source.getActiveRange();
  var editColumn = actRng.getColumn();
  var index = actRng.getRowIndex();
  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues();
  var dateCol = headers[0].indexOf(timeStampColName);
  var updateCol = headers[0].indexOf(updateColName); updateCol = updateCol+1;
  if (dateCol > -1 && index > 1 && editColumn == updateCol) { // only timestamp if 'Last Updated' header exists, but not in the header row itself!
    var cell = sheet.getRange(index, dateCol + 1);
    var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
    cell.setValue(date);
  }
}
  

绑定到Button的命令执行此操作。

   private static Grid _myMainGrid;

    public static Grid MyMainGrid
    {
        get { return _myMainGrid; }
        set { _myMainGrid = value; }
    }

    private void OpenUserControl(UserControl myUS)
    {
        if (MyMainGrid.Children.Count > 0)
        {
            MyMainGrid.Children.RemoveAt(0);
        }
        Grid.SetColumn(myUS, 1);
        Grid.SetRow(myUS, 0);
        MyMainGrid.Children.Add(myUS);
    }
    private void FindGrid(object obj)
    {
        var myGrd = obj as Grid;
        if (myGrd != null)
        {
            MyMainGrid = myGrd;
        }
    }

现在我想通过按Usercontrol1中的按钮打开Usercontrol2,从我的MainWindow替换MyMainGrid中的Usercontrol1。所以我必须访问父窗口。

尝试使用this methode,但无法在我的案例中使用它。

2 个答案:

答案 0 :(得分:1)

假设你有两个孩子;将这一点推广到任何数量的孩子都是微不足道的。幸运的是,你已经拥有了视图模型和视图,所以我们大部分都在这里。只需将它们连接在一起,就可以与WPF一起使用。

这是一组骨架视图模型。主,和两个孩子。 MainViewModel创建了两个子实例。 ChildOneViewModel有一个Next按钮命令,绑定到ChildOneView.xaml中的Button

当用户点击该按钮时,我们希望将活动视图切换为子二。 ChildOneViewModel并不是指向所有方向的依赖关系,而是忽视“下一个”的真正含义;它的父母MainViewModel负责这一点。每个人都知道他的孩子;你发现在编程中,让一个类知道它的兄弟姐妹或它的父母会产生问题。

所以ChildOneViewModel所做的就是公开一个事件,以便MainViewModel知道点击按钮的时间,并在发生这种情况时采取任何喜欢的行动。这很酷,因为如果我们可以转到两个不同的“下一页”中的一个,取决于用户在ChildOne中做了什么?如果我们将这一责任移交给父母,一切都变得更加简单。更容易编写,更容易在不同的上下文中重用。

#region MainViewModel Class
public class MainViewModel : ViewModelBase
{
    public MainViewModel()
    {
        ChildOne = new ChildOneViewModel();
        ChildTwo = new ChildTwoViewModel();

        ActiveChild = ChildOne;

        ChildOne.NextButtonClicked += (s, e) => ActiveChild = ChildTwo;
    }

    #region ActiveChild Property
    private INotifyPropertyChanged _activeChild = default(INotifyPropertyChanged);
    public INotifyPropertyChanged ActiveChild
    {
        get { return _activeChild; }
        set
        {
            if (value != _activeChild)
            {
                _activeChild = value;
                OnPropertyChanged();
            }
        }
    }
    #endregion ActiveChild Property

    public ChildOneViewModel ChildOne { get; private set; }
    public ChildTwoViewModel ChildTwo { get; private set; }
}
#endregion MainViewModel Class

#region ChildOneViewModel Class
public class ChildOneViewModel : ViewModelBase
{
    public event EventHandler NextButtonClicked;

    //  You already know how to implement a command, so I'll skip that. 
    protected void NextButtonCommandMethod()
    {
        NextButtonClicked?.Invoke(this, EventArgs.Empty);
    }
}
#endregion ChildOneViewModel Class

#region ChildTwoViewModel Class
public class ChildTwoViewModel : ViewModelBase
{
}
#endregion ChildTwoViewModel Class

这是XAML在运行时将所有内容转换为实际UI:

<Window.Resources>
    <!-- 
    These are "implicit datatemplates": They have no x:Key, so they'll be 
    automatically used to display any content of the specified types. 
    -->
    <DataTemplate DataType="{x:Type local:ChildOneViewModel}">
        <local:ChildOneView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:ChildTwoViewModel}">
        <local:ChildTwoView />
    </DataTemplate>
</Window.Resources>
<Grid>

    <!-- other stuff -->
    <UserControl
        Content="{Binding ActiveChild}"
        />
    <!-- other stuff -->

您不需要OpenUserControl()FindGrid(),任何这些东西。

答案 1 :(得分:-1)

我并不完全了解您的应用程序的结构,并且最有可能更好地完成您尝试做的任何事情,但您可以使用Application.Current.Windows获取应用程序中任何打开的窗口的引用财产,如果这是你的主要问题:

var mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();

加载的 UserControl中,您还应该能够像这样获得对此UserControl的父窗口的引用:

var mainWindow = Window.GetWindow(this) as MainWindow;