我正在开发一个包含大量数据输入表单的WPF应用程序。我已将这些表单中的每一个作为单独的用户控件公开。所以,我有CustomerView(UserControl),CompaniesView(UserControl)。每个表单都包含用户输入的客户名称,公司名称等字段,然后保存它们。
使用工具栏执行保存操作,该工具栏包含“保存”,“删除”和“关闭”选项。我已将Toolbar创建为一个单独的UserControl,并将其放在容器视图/ shell视图中。以下是将要明确的事情结构。
CONTAINER BEGINS
--------------------------------------------------------------------
-----------------------------------
THIS IS THE TOOLBAR
----------------------------------
______________________________________
Data Entry forms are injected here on the fly
______________________________________
---------------------------------------------------------------------
CONTAINER ENDS
问题是,当我单击工具栏中的“保存”按钮时,我不知道有关包含表单的视图的任何信息。我需要掌握附加到该视图的MVVM模型,以便我可以保存它。
答案 0 :(得分:0)
我使用UserControls处理这个问题的方法是我的shell视图模型将引用ToolbarViewModel和DataEntryViewModel。工具栏将有一个事件触发每个可能的命令,shell视图模型将适当地处理事件。这是一个例子:
在MainView中,我为每个可能的DataEntry视图/视图模型创建了一个DataTemplate。然后将ContentPresenter绑定到DataEntryViewModel的基本类型的MainViewModel中的属性。
<Window
//usual window declarations>
<Window.Resources>
<DataTemplate DataType="{x:Type vm:DataEntryViewModel}">
<view:DataEntryView />
</DataTemplate>
//more DataTemplates for other data entry views
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<view:ToolbarView Grid.Row="0"
DataContext="{Binding ToolbarContext}" />
<ContentPresenter Grid.Row="1"
Content="{Binding DataEntryContext}" />
</Grid>
</Window>
DataEntryViewModel将拥有一个方法,用于工具栏可能要对其执行的所有不同操作。为了简洁起见,我在这里只提供了Save方法。
public interface IDataEntryViewModelBase
{
void Save();
}
public abstract class DataEntryViewModelBase : ViewModelBase, IDataEntryViewModelBase
{
public virtual void Save()
{
//base save work
}
}
public class DataEntryViewModel : DataEntryViewModelBase
{
public override void Save()
{
base.Save();
//unique save work
}
}
ToolbarViewModel为每个可执行的命令都有一个事件。
public class ToolbarViewModel : ViewModelBase, IToolbarViewModel
{
//can just use EventArgs here if no need to pass data when this event fires
public event EventHandler<SaveExecutedArgs> SaveExecuted;
public ICommand CmdSave
{
get { return new RelayCommand(() => OnSaveExecuted()); }
}
protected void OnSaveExecuted()
{
var handler = SaveExecuted;
if (handler == null) return;
handler(this, new SaveExecutedArgs());
}
}
MainViewModel具有Toolbar的DataContext属性和DataEntry DataContext的属性。分配ToolbarContext时,我为工具栏公开的每个命令事件注册一个方法。在eventhandler中,我为事件调用了DataEntryContext的适当方法。
public class MainViewModel : ViewModelBase
{
private IToolbarViewModel _toolbarContext;
public IToolbarViewModel ToolbarContext
{
get { return _toolbarContext; }
set { Set("ToolbarContext", ref _toolbarContext, value); }
}
private IDataEntryViewModelBase _dataEntryContext;
public IDataEntryViewModelBase DataEntryContext
{
get { return _dataEntryContext; }
set { Set("DataEntryContext", ref _dataEntryContext, value); }
}
public MainViewModel()
{
_toolbarContext = new ToolbarViewModel();
_toolbarContext.SaveExecuted += ToolbarContext_SaveExecuted;
_dataEntryContext = new DataEntryViewModel();
}
private void ToolbarContext_SaveExecuted(object sender, SaveExecutedArgs e)
{
//can change this to popup a warning or however you want to handle it
//under the circumstance that DataEntryContext is null
if (DataEntryContext == null) return;
DataEntryContext.Save();
}
}