将 class 属性绑定到 MVVM 中的 UserControl
Binding class properties to UserControl in MVVM
我有一个 class,其中包含一个名为 Text 的字符串 属性。
public class Time
{
private string _text;
public string Text
{
get { return _text; }
set { _text = value; }
}
}
我还有一个包含此 class 的自定义用户控件。
public partial class MyUserControl : UserControl, INotifyPropertyChanged
{
<...>
private Time _myTime;
public Time MyTime
{
get { return _myTime; }
set { _myTime= value; NotifyPropertyChanged(); }
}
}
在我的 ViewModel 中,我想创建上面的 UserControl 并为其分配时间 class 及其所有属性:
void SomeMethod()
{
Time TestTime = new Time();
TestTime.Text = "Hello world";
MyUserControl control = new MyUserControl();
control.MyTime = TestTime;
controlViewer = new System.Collections.ObjectModel.ObservableCollection<Control>();
controlViewer.Add(control);
// on my main window, I have an ItemsControl with
// ItemsSource="{Binding controlViewer}".
}
UserControl 的 XAML 包含此文本框:
<TextBox Text="{Binding MyTime.Text}"/>
然后我能够以编程方式调用 control.MyTime.Text 属性 并获得 "Hello world" 值就好了——但我无法在新创建的 MyUserControl 上显示它文本框。
您必须将绑定的源对象设置为 UserControl 实例,例如通过像这样设置绑定的 RelativeSource
属性:
<TextBox Text="{Binding MyTime.Text,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
除此之外,在视图元素中实现 INotifyPropertyChanged
接口并不常见。您可以改为将 MyTime
声明为依赖项 属性:
public static readonly DependencyProperty MyTimeProperty =
DependencyProperty.Register("MyTime", typeof(Time), typeof(MyControl));
public Time MyTime
{
get { return (Time)GetValue(MyTimeProperty); }
set { SetValue(MyTimeProperty, value); }
}
在您的 ViewModel 中创建 UserControl 不是很好的做法。
尝试用下一种方式做到这一点:
- 使用 ItemsControl 创建 XAML 主 window(ListView/ListBox 更好,因为它们允许选择)。
- 使用 ObservableCollection of Time class 个对象创建 ViewModel,然后将此 ViewModel 作为视图模型绑定到 MainWindow。
- 使用您希望在集合中看到的对象初始化 ViewModel。
- 使用 UserControl 为每个 ItemsControl 集合成员定义 DataTemplate。
此致,
我有一个 class,其中包含一个名为 Text 的字符串 属性。
public class Time
{
private string _text;
public string Text
{
get { return _text; }
set { _text = value; }
}
}
我还有一个包含此 class 的自定义用户控件。
public partial class MyUserControl : UserControl, INotifyPropertyChanged
{
<...>
private Time _myTime;
public Time MyTime
{
get { return _myTime; }
set { _myTime= value; NotifyPropertyChanged(); }
}
}
在我的 ViewModel 中,我想创建上面的 UserControl 并为其分配时间 class 及其所有属性:
void SomeMethod()
{
Time TestTime = new Time();
TestTime.Text = "Hello world";
MyUserControl control = new MyUserControl();
control.MyTime = TestTime;
controlViewer = new System.Collections.ObjectModel.ObservableCollection<Control>();
controlViewer.Add(control);
// on my main window, I have an ItemsControl with
// ItemsSource="{Binding controlViewer}".
}
UserControl 的 XAML 包含此文本框:
<TextBox Text="{Binding MyTime.Text}"/>
然后我能够以编程方式调用 control.MyTime.Text 属性 并获得 "Hello world" 值就好了——但我无法在新创建的 MyUserControl 上显示它文本框。
您必须将绑定的源对象设置为 UserControl 实例,例如通过像这样设置绑定的 RelativeSource
属性:
<TextBox Text="{Binding MyTime.Text,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
除此之外,在视图元素中实现 INotifyPropertyChanged
接口并不常见。您可以改为将 MyTime
声明为依赖项 属性:
public static readonly DependencyProperty MyTimeProperty =
DependencyProperty.Register("MyTime", typeof(Time), typeof(MyControl));
public Time MyTime
{
get { return (Time)GetValue(MyTimeProperty); }
set { SetValue(MyTimeProperty, value); }
}
在您的 ViewModel 中创建 UserControl 不是很好的做法。 尝试用下一种方式做到这一点:
- 使用 ItemsControl 创建 XAML 主 window(ListView/ListBox 更好,因为它们允许选择)。
- 使用 ObservableCollection of Time class 个对象创建 ViewModel,然后将此 ViewModel 作为视图模型绑定到 MainWindow。
- 使用您希望在集合中看到的对象初始化 ViewModel。
- 使用 UserControl 为每个 ItemsControl 集合成员定义 DataTemplate。
此致,