Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在MVVM中构造对象时,如何将对象传递给ViewModel?_C#_Wpf_Mvvm_Properties_Dependencies - Fatal编程技术网

C# 在MVVM中构造对象时,如何将对象传递给ViewModel?

C# 在MVVM中构造对象时,如何将对象传递给ViewModel?,c#,wpf,mvvm,properties,dependencies,C#,Wpf,Mvvm,Properties,Dependencies,我有一个模型 public class VM: DependencyObject, INotifyPropertyChanged { public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } // Using a DependencyProperty as the back

我有一个模型

public class VM: DependencyObject, INotifyPropertyChanged
{
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(VM), new PropertyMetadata(""));

    public int Length 
    { 
        get
        {
            return Text != null ? Text.Length : 0;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}
和它的视图

<UserControl.DataContext>
    <local:VM Text="{Binding ControlText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"/>
</UserControl.DataContext>

<StackPanel>
    <TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}"/>
    <TextBlock Text="{Binding Length}"/>
</StackPanel>
我在输出日志上出错

System.Windows.Data错误:4:找不到引用为“RelativeSource FindAncestor,AncestorType='System.Windows.Controls.UserControl',AncestorLevel='1'的绑定源。BindingExpression:Path=ControlText;DataItem=null;目标元素为“VM”(HashCode=21019086);目标属性为“Text”(类型为“String”)

当这项技术起作用时,我将拥有构建viewmodel的工具。
也许任何人都知道如何将此视图属性绑定到viewmodel属性,或者知道如何正确执行此操作的技术:)

如果在XAML中声明
DataContext
,它将在加载XAML时初始化。另外,
VM
不像UserControl那样位于可视化树中,因此
RelativeSource
不能在这里工作

但您可以在代码隐藏中通过从UserControl的构造函数设置DataContext并在那里进行绑定来实现这一点:

public MainWindow()
{
   InitializeComponent();
   VM viewModel = new VM();
   DataContext = viewModel;
   Binding binding = new Binding("ControlText") { Source = this };
   BindingOperations.SetBinding(viewModel, VM.TextProperty, binding);
}

你似乎对一些事情有些困惑。如果您想在XAML中将视图模型设置为
UserControl.DataContext
,这是可以的,但是您不需要从那里将数据绑定到控件:

<UserControl.DataContext>
    <local:VM  />
</UserControl.DataContext>
现在,如果您想从XAML访问
ControlText
属性,则需要使用
RelativeSource绑定。但是,请注意,您应该如何按其名称/类型引用
UserControl
,而不使用
UserControl
,因为正如错误所述,
UserControl
中没有定义
ControlText
属性。试试这个:

<StackPanel>
    <TextBox Text="{Binding ControlText, RelativeSource={RelativeSource 
        AncestorType={x:Type local:YourUserControl}} />
    <TextBlock Text="{Binding Length}"/>
</StackPanel>

更新>>>

在使用MVVM时,我们通常不会尝试通过
ui元素将数据从一个数据源传递到另一个数据源。相反,我们更喜欢将数据从一个数据项传递到另一个数据项。您的问题是您正在视图中实例化视图模型。。。相反,在父视图模型中实例化它,并传入所需的任何值,然后从父视图中的控件外部将其设置为
UserControl.DataContext
属性值:

<local:YourUserControl DataContext="{Binding YourChildViewModelPropertyInParentVM}" />


一旦在视图模型中有了正确的值,就不需要使用
ControlText
属性。

我知道在,您向我展示的最后一个部分是我在Writer(UserCntrol)中创建Dependency属性的主要原因。但是我想让大家这样想:我有string属性string s{get;set;}我创建了Writer(UserControl),并通过绑定将这个字符串传递给创建的UserControl。现在我需要一个UserCOntrol将属性传递到Viewmodel。因此,我试图在Writer.xaml中实现这一点,即通过视图构建Viewmodel。属性s正在通过视图拖动到viewmodel
<StackPanel>
    <TextBox Text="{Binding ControlText, RelativeSource={RelativeSource 
        AncestorType={x:Type local:YourUserControl}} />
    <TextBlock Text="{Binding Length}"/>
</StackPanel>
<local:YourUserControl ControlText="{Binding SomeStringProperty}" />
<local:YourUserControl DataContext="{Binding YourChildViewModelPropertyInParentVM}" />