【问题标题】:Wpf Prism - Passing parameter from view to viewmodelWpf Prism - 将参数从视图传递到视图模型
【发布时间】:2017-01-24 22:01:55
【问题描述】:

我创建了一个视图 (MyView),其中包含这样的 UserControl:

<StackPanel>
  <ctrl:ViewDialog DataContext="{Binding CtrlViewDialog}" Message="Hello" Name="ctrlViewDialog" >                     
</ctrl:ViewDialog>

视图背后的代码:

public MyView()
        {
            InitializeComponent();
            var _message = ctrlViewDialog.Message;
        }

        [Dependency]
        public MyViewViewModel ViewModel
        {
            get
            {
                return (MyViewViewModel)this.DataContext;
            }
            set
            {

                this.DataContext = value;
            }
        }

而视图模型 MyViewViewModel 是:

public MyViewViewModel()
        {         

            ViewDialogViewModel CtrlViewDialog = new ViewDialogViewModel(Message);
        }

包含的UserControl(ViewDialog)背后的代码是:

private string message;
        public string Message
        {
            get { return message; }
            set { message = value; }
        }


        public ViewDialog()
        {
            InitializeComponent();
        }

如何将 MyView 的 "_message" 参数传递给 MyViewViewModel 以便将其传递给实例 ViewDialogViewModel CtrlViewDialog = new ViewDialogViewModel(Message);

【问题讨论】:

  • 您确定这是您想要做的吗?使用(MyViewViewModel)this.DataContext;在视图中通常是你没有做正确的事情的标志。您在 prism 中使用 DI 做什么?
  • 好的 Filip,我可以删除 (MyViewViewModel)this.DataContext;但我想将 Message="Hello" (xaml) 从视图传递到视图模型。有没有其他办法?

标签: c# wpf mvvm prism code-behind


【解决方案1】:

好的,我将尝试回答您实际提出的树问题。 首先与c#有关。你能做到吗?

public MyViewViewModel()
{      
     ViewDialogViewModel CtrlViewDialog = new ViewDialogViewModel(Message);
}

没有一个构造函数会在你填充属性之前一直运行。

其次,您能否使用 WPF 将此值从您的视图传递到您的视图模型? 是的。它也可以在构造函数中完成,但这需要更多代码。当控件更容易加载时,您可以这样做。

<UserControl
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:vm="clr-namespace:PrismTest.ViewModels"
             xmlns:view="clr-namespace:PrismTest.Views"
             x:Class="PrismTest.Views.TestView"
             prism:ViewModelLocator.AutoWireViewModel="True">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding LoadedCommand}" CommandParameter="{Binding Message, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type view:TestView}}}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Grid>
        <StackPanel>
            <TextBlock Text="{Binding Message, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type view:TestView}}}"/>
            <TextBlock Text="{Binding Message}"/>
        </StackPanel>
    </Grid>
</UserControl> 

命令

 private ICommand loadedCommand = new DelegateCommand<string>(text => 
        {
            MessageBox.Show(text);
        });
        public ICommand LoadedCommand { get { return loadedCommand; } }

现在这是您应该在 prism 中做的事情吗?很好的传递参数是的。这样做ViewDialogViewModel CtrlViewDialog = new ViewDialogViewModel(Message); 和这个

(MyViewViewModel)this.DataContext;

不!如果要使用 prism,依赖注入是最重要的部分。你可能想看看thisthis

【讨论】:

  • Filip构造函数中的“Message”不是控件的属性,抱歉使用了同名;)。您建议的其余代码工作正常。是一个很好的解决方案
  • 很高兴我能帮上忙。仅指出仅当 Massage 属性是没有设置器 Massage{ get{ return "SOME FIX VALUE"; } } 的只读属性时,您可以在构造函数中使用它,在新的 ViewModel(){ Message = "Some Value" } 中使用它将始终先运行构造函数,然后运行属性设置器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
相关资源
最近更新 更多