【问题标题】:wpf usercontrol data-binding using xaml使用 xaml 的 wpf 用户控件数据绑定
【发布时间】:2013-01-16 12:47:55
【问题描述】:

我有这样的 wfp 表格:

public partial class MediaPlayerControlMain : Window
{
    MediaPlayerMain MediaPlayerMain;

    public MediaPlayerControlMain()
    {
        MediaPlayerMain = new MediaPlayerMain();
        InitializeComponent();
    }
}

我有使用 MediaPlayerMain 对象的用户控件 (PlayList)。 该用户控件具有:

public partial class PlayList : UserControl
{
    public MediaPlayerMain MediaPlayer
    {
        get { return (MediaPlayerMain)GetValue(MediaPlayerProperty); }
        set { SetValue(MediaPlayerProperty, value); }
    }

    public static readonly DependencyProperty MediaPlayerProperty =
        DependencyProperty.Register(
            "MediaPlayer", typeof(MediaPlayerMain), typeof(PlayList),
            new FrameworkPropertyMetadata()
        );

}

有没有办法只使用 xaml 设置 MediaPlayer 属性。我尝试使用“{Binding ElementName=MediaPlayerMain}”,但似乎 MediaPlayerMain 尚未初始化。虽然我在 InitializeComponent() 函数之前对其进行了初始化。我究竟做错了什么?。将该对象传递给我的用户控件的最佳选择是什么?

【问题讨论】:

  • MediaPlayerMain 类有两个对象吗?一个在主窗口中,一个在用户控件中?在代码的第一部分,您只在主窗口中创建新对象
  • 不,MediaPlayerMain 只有一个对象,用户控件应该使用它。这有点像委托。
  • 能否请您显示 MediaPlayerMain 类。
  • 我还没写完呢。在这里发布它是相当大的。可能我会将它发布在 sourceforge.net 或 github 或类似的地方。

标签: c# wpf data-binding user-controls


【解决方案1】:
public partial class MediaPlayerControlMain : Window,INotifyPropertyChanged
    {


        public MediaPlayerControlMain()
        {                
            InitializeComponent();
            MediaPlayerMain = new MediaPlayerMain();
        }
        private MediaPlayerMain mediaPlayerMain;

        public MediaPlayerMain MediaPlayerMain
        {
            get { return mediaPlayerMain; }
            set { mediaPlayerMain = value; Notify("MediaPlayerMain"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void Notify(string propName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propName));

        }
    }

 "{Binding MediaPlayerMain RelativeSource={RelativeSource AncestorType=Window}}"

问题是你试图绑定字段而不是属性。因为绑定源必须是属性而不是字段,因为绑定系统使用反射并且只查找属性而不是字段。我希望这会帮助。

【讨论】:

    【解决方案2】:

    您需要在标记中命名您的根元素(Window/UserControl 本身)。即:

    <Window x:Name="mediaPlayer"
        ....>
        <TextBlock Text="{Binding SomeProperty,ElementName=mediaPlayer}"
    

    【讨论】:

    • 如果他不使用 MVVM,这是最简单的方法。
    【解决方案3】:

    我没有看到您在任何地方设置 DataContext,我认为您的 XAML 树中没有名为 MediaPlayerMain 的对象

    当您编写 {Binding ElementName=MediaPlayerMain} 时,您是在告诉 WPF 将属性设置为等于可视树中名为 MediaPlayerMain 的 XAML 对象

    您可能正在寻找的是绑定到名为 MediaPlayerMain 的 DataContext 中的属性,在这种情况下,您的绑定将如下所示:

    <local:PlayList MediaPlayer="{Binding MediaPlayerMain}" />
    

    但是除非你的DataContext被设置为一个包含MediaPlayerMain属性的对象,否则这不会起作用,比如在你的Window的构造函数中设置this.DataContext = this

    作为替代方案,您可以在绑定中使用 ElementName 来告诉 WPF 在可视树中查找对象的属性,而不是在 DataContext 中查找属性,例如您的 Window

    <local:MediaPlayerControlMain x:Name="MainWindow" ...>
        <local:PlayList MediaPlayer="{Binding MediaPlayerMain, ElementName=MainWindow}" />
    </local:MediaPlayerControlMain>
    

    这将使您的绑定在名为 MainWindow 的 XAML 元素中查找属性 MediaPlayerMain,这是您的 MediaPlayerControlMain 类。

    如果您不熟悉 WPF 的 DataBinding,实际上我的博客上有一篇专门针对初学者的文章,可以帮助您更好地了解它是什么以及它是如何工作的:What is this "DataContext" you speak of?

    【讨论】:

    • 谢谢你,瑞秋。我已阅读您的文章,它帮助我更好地理解绑定。
    猜你喜欢
    • 1970-01-01
    • 2012-04-15
    • 2011-04-01
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    相关资源
    最近更新 更多