我正在尝试创建UserControl,以便以后在WPF应用程序中重用它们。我选择建立一个小项目来训练自己,但我无法使其正常工作。

目的是要创建一个TextBox,其内容将通过单击Button来作为Label Text发送。

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


XAML Binding on Dependency Property
Custom Dependency Properties
Simple Dependency Property and UserControl issues in C#
Add dependency property to control


但是,即使我在构造函数中设置的起始文本也不会显示,并且单击按钮根本不起作用。

这是我的文件:

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));
            }
        }
    }
}


非常感谢您的帮助!

最佳答案

您正在窗口的代码背后创建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}"

关于c# - 绑定(bind)UserControl的依赖项属性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45190571/

10-12 12:36
查看更多