绑定UserControl的依赖属性

时间:2017-07-19 12:26:30

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

我正在尝试创建UserControl,以便以后在WPF应用程序中重用它们。我选择建立一个小项目来训练自己,但我不能让它发挥作用。

目标是拥有一个TextBox,其内容将作为标签文本发送,点击按钮。

我已阅读并尝试了这些链接上的解决方案:

但即使我在构造函数中设置的起始文本也没有显示,按钮点击也什么也没做。

以下是我的文件:

MyControl.xaml

<UserControl x:Class="WpfApplication1.MyControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApplication1"
             mc:Ignorable="d" 
             Name="control"
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBox Text="{Binding TextBoxContent,ElementName=control}"/>
        <Button Content="Print Entry" Grid.Row="1" Command="{Binding ButtonCommmand,ElementName=control}"/>
        <Label Grid.Row="2" Content="{Binding LabelContent,ElementName=control}"/>
    </Grid>
</UserControl>

MyControl.xaml.cs

using GalaSoft.MvvmLight.CommandWpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    public partial class MyControl : UserControl
    {
        public MyControl()
        {
            InitializeComponent();
            ButtonCommmand = new RelayCommand(Action);
        }

        public string TextBoxContent
        {
            get
            {
                return (string)GetValue(TextBoxContentProperty);
            }
            set
            {
                SetValue(TextBoxContentProperty, value);
            }
        }
        public RelayCommand ButtonCommmand
        {
            get
            {
                return (RelayCommand)GetValue(ButtonCommandProperty);
            }
            set
            {
                SetValue(ButtonCommandProperty, value);
            }
        }

        public string LabelContent {
            get
            {
                return (string)GetValue(LabelContentProperty);
            }
            set
            {
                SetValue(LabelContentProperty, value);
            }
        }

        public void Action()
        {
            LabelContent = TextBoxContent;
        }

        public static readonly DependencyProperty TextBoxContentProperty = DependencyProperty.Register("TextBoxContent", typeof(string), typeof(MyControl), new PropertyMetadata(""));

        public static readonly DependencyProperty ButtonCommandProperty = DependencyProperty.Register("ButtonCommmand", typeof(RelayCommand), typeof(MyControl), new PropertyMetadata(null));

        public static readonly DependencyProperty LabelContentProperty = DependencyProperty.Register("LabelContent", typeof(string), typeof(MyControl), new PropertyMetadata(""));
    }
}

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:control="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <control:MyControl DataContext="{Binding customControl}" TextBoxContent="{Binding Text,Mode=TwoWay}" LabelContent="{Binding EndText,Mode=TwoWay}" ButtonCommmand="{Binding Command,Mode=TwoWay}"/>
    </Grid>
</Window>

MainWindow.xaml.cs

using GalaSoft.MvvmLight.CommandWpf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication1
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        MyControl customControl = new MyControl();
        public MainWindow()
        {
            InitializeComponent();
            Command = new RelayCommand(Action);
            Text = "Testing... Testing... 1, 2, 3,...";
        }

        private string text;
        public string Text
        {
            get
            {
                return text;
            }
            set
            {
                text = value;
                NotifyPropertyChanged();
            }
        }
        private string endText;
        public string EndText
        {
            get
            {
                return endText;
            }
            set
            {
                endText = value;
                NotifyPropertyChanged();
            }
        }
        private RelayCommand command;
        public RelayCommand Command
        {
            get
            {
                return command;
            }
            set
            {
                command = value;
                NotifyPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void Action()
        {
            EndText = Text;
        }

        private void NotifyPropertyChanged([CallerMemberName]string PropertyName = "")
        {
            if (!String.IsNullOrEmpty(PropertyName))
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
    }
}

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:1)

您正在窗口的代码隐藏中创建UserControl的另一个实例:

MyControl customControl = new MyControl();

您要做的是将您在XAML中定义的UserControl的属性绑定到窗口的属性。为此,您应该将窗口的DataContext设置为自身:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Command = new RelayCommand(Action);
        Text = "Testing... Testing... 1, 2, 3,...";
    }
}

...并从您的XAML中删除它:

DataContext="{Binding customControl}"