wpf - 在没有绑定(bind)的情况下通过 DataContext 从 ViewModel 获取值(value)?

标签 wpf mvvm user-controls wpf-controls

WPF 的新手。我正在创建需要对 ViewModel 状态进行读取访问才能执行其操作的 UserControl。我目前使用以下技术:

public partial class ControlBar : UserControl
{

    private static readonly DependencyProperty URLProperty =
        DependencyProperty.Register("URL", typeof(string), typeof(ControlBar),
        new UIPropertyMetadata(null));

    public ControlBar()
    {
        InitializeComponent();

        SetBinding(URLProperty, "CurrentPage.URL");

        Pin.Click += Pin_Click;       
    }

    private void Pin_Click(object sender, RoutedEventArgs e)
    {
        var URL = (string)GetValue(URLProperty);

    }
}

这是正确的方法吗?为我需要访问的每个变量设置长期绑定(bind)不是大材小用吗?或者您可以执行以下操作:
GetValue(new Path("CurrentPage.URL..... 

我显然弥补了以上内容。

谢谢!

最佳答案

一般来说,数据绑定(bind)是要走的路。但是,有时当您创建的控件具有特定于 View 的问题时,数据绑定(bind)将不适合。

在这些情况下,您将希望能够与 DependencyProperty 交互以设置它并知道它何时更改。我一直遵循从 MSDN 杂志上的 Charles Petzold 文章中获得的模式。

我对另一个问题的回答显示了为 UserControl Stack Overflow: Dependency Property In WPF/SilverLight 创建 DependencyProperty 的模式

同样,数据绑定(bind)到 View 模型可能会解决您的问题,但 DependencyProperty 可能会根据情况派上用场。

更新以回应评论:

在许多情况下,您可以在 UserControl 中进行数据绑定(bind),而无需使用 DependencyProperty。例如,如果您有一个显示名称的 TextBlock,您可以在 UserControl 的 XAML 中放置一个 TextBlock

<TextBlock Text="{Binding Path=NameString}" />

在 DataContext 中存在的 View 模型中,您将有一个属性 NameString 并且如果 TextBlock 要在 NameString 属性更改时更新显示,则 View 模型应实现 INotifyPropertyChanged 并且该属性应使用属性名称触发 PropertyChanged 事件随事件一起发送。
protected string _NameString;
public string NameString
{
    get { return _NameString; }
    set { _NameString = value: Notify("NameString"); }
}

其中 Notify 是检查 PropertyChanged 事件是否为 null 并在不为 null 时发送事件的方法。

如果您想使用 UserControl 的任何地方都有一个带有 Name 属性的 View 模型,那么这很有效。最棒的是,UserControl 可以获取它所在位置的 DataContext 并绑定(bind)到外部 View 模型。

当您想开始将相同的 UserControl 绑定(bind)到不同的属性时,您可能需要使用 DependencyProperty。在这种情况下,您可以使用 DependencyProperty 创建 UserControl 并将其绑定(bind)到不同的属性
<my:SampleControl NameString="{Binding Path=GivenName}" />
<my:SampleControl NameString="{Binding Path=FamilyName}" />

然后有一个内部 View 模型,当绑定(bind)属性更改时,DependencyProperty 更改处理程序会更新。

更新:没有 DependencyProperty 或绑定(bind)

您始终可以向 UserControl 添加一个普通的 C# 属性并以这种方式传递数据。
public MyClass Data { get; set; }

然后在 UserControl 的代码隐藏中,您可以简单地使用该属性:
if (this.Data != null)
{
    this.textBox1.Text = Data.NameString;
}

更新以回应评论:

在代码中访问 View 模型的另一种方法是将 DataContext 转换为您的 View 模型类型:
MyClass data = this.DataContext as MyClass;
if (data != null)
{
    // do something
    this.textBox1.Text = data.NameString;
}

关于wpf - 在没有绑定(bind)的情况下通过 DataContext 从 ViewModel 获取值(value)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9437107/

相关文章:

c# - WPF 正确处理 View 和 View 模型

mvvm - FreshMvvm-PopPageModel在Android上不起作用

javascript - TrackballControls - "staticMoving"属性有什么作用?

c# - 如果数据绑定(bind),如何将表单/字段标记为 "dirty"?

wpf - 在WPF应用程序中查找所有打开的弹出窗口

c# - 用于图表应用程序的 html5/JavaScript 或 WPF/C#

c# - 全面实现中继命令 - 它可以应用于所有情况吗?

windows-phone-7 - 如何在Mvvm Light中清理ViewModel?

c# - 如何有条件地将 UserControl 添加到中继器控件?

c# - MVVM Light - 用户控件作为 View