【问题标题】:Using a custom attached property with a binding使用带有绑定的自定义附加属性
【发布时间】:2011-09-17 13:43:30
【问题描述】:

我正在查看this question,但我不明白如何实际使用创建的 AttachedProperty。问题是试图对 WebBrowser 控件的源进行绑定。

那里的代码如下:

public static class WebBrowserUtility
{
public static readonly DependencyProperty BindableSourceProperty =
    DependencyProperty.RegisterAttached("BindableSource", typeof(string), typeof(WebBrowserUtility), new UIPropertyMetadata(null, BindableSourcePropertyChanged));

public static string GetBindableSource(DependencyObject obj)
{
    return (string) obj.GetValue(BindableSourceProperty);
}

public static void SetBindableSource(DependencyObject obj, string value)
{
    obj.SetValue(BindableSourceProperty, value);
}

public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    WebBrowser browser = o as WebBrowser;
    if (browser != null)
    {
            string uri = e.NewValue as string;
            browser.Source = uri != null ? new Uri(uri) : null;
    }
}
}

<WebBrowser ns:WebBrowserUtility.BindableSource="{Binding WebAddress}"
            ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
            ScrollViewer.VerticalScrollBarVisibility="Disabled" 
            Width="300"
            Height="200" />

网址,究竟是什么?这是我的理解(可能是错误的):

  • 有一个 AttachedProperty 可以附加到任何对象,在这种特殊情况下,它基本上只是附加一个名为 BindableSource 的 String 类型的属性。
  • 当我们拥有“{Binding WebAddress}”时,这意味着在处理此 .xaml 文件的某些 c# 代码中,有如下内容:

    public String WebAddress
    { 
        // get and set here? not sure
    }
    
  • 为了利用已更改的属性,我可以调用 RaisedPropertyChanged,它会在那里触发该静态方法?

即使我看着它,它似乎也不对,但我在网上找不到任何可以帮助我的东西。

【问题讨论】:

    标签: c# wpf data-binding browser webbrowser-control


    【解决方案1】:

    有一个 AttachedProperty 可以附加到任何对象,在这种特殊情况下,它基本上只是附加一个名为 BindableSource 的属性,它是 String 类型的。

    您可能想阅读MSDN article on attached properties

    这相当简单:Dependency properties 使用字典,其中控件与其属性的值相关联,这使得添加诸如可以扩展控件的附加属性之类的东西变得非常容易。

    在附加属性的RegisterAttached 方法中,连接了PropertyChangedCallback,如果值更改,将执行该方法。使用依赖属性可以启用绑定,这首先是这样做的重点。该属性真正所做的只是在值发生变化时调用相关代码来导航浏览器。


    当我们有“{Binding WebAddress}”时,这意味着在处理此 .xaml 文件的某些 c# 代码中,有一些看起来像 [...]

    绑定引用了 WebBrowser 的 DataContext 内称为 WebAddress 的一些公共 property 或依赖属性(不是 field)。有关数据绑定的一般信息,请参阅Data Binding Overview

    因此,如果您想创建一个应该作为绑定源的属性,您可以实现 INotifyPropertyChanged 或创建一个 DependencyProperty(它们自己触发更改通知,您通常只在控件和 UI 相关类上创建这些通知)

    您的属性可能如下所示:

    public class MyModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    
        private string _webAddress;
        public string WebAddress
        {
            get { return _webAddress; }
            set
            {
                if (value != _webAddress)
                {
                    _webAddress = value;
                    NotifyPropertyChanged("WebAddress");
                }
            }
        }
    }
    

    在这里,您必须在 setter 中引发 PropertyChanged 事件,正如您所怀疑的那样。如何在 XAML 中实际声明有效绑定是一个相当广泛的主题,我想再次将您引导至上述Data Binding Overview,这应该可以解释这一点。


    为了利用属性更改,我可以调用 RaisedPropertyChanged,它会在那里触发那个静态方法?

    触发该事件以触发绑定更新,这反过来会更改附加属性的值,从而导致 PropertyChangedCallback 被执行,最终导航浏览器。

    【讨论】:

    • 实际上,OP 可能确实想要在实现 WebAddress 属性的 ViewModel 类中引发 PropertyChanged 事件
    • @pickles:嗯,这听起来很合理。
    • @pickles:我大大更新了我的答案,现在希望能解决所有问题。
    猜你喜欢
    • 1970-01-01
    • 2012-03-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 2012-09-24
    • 2017-08-21
    相关资源
    最近更新 更多