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}" />