如何将属性绑定到 wpf 中 UserControl 中的 DependencyObject?

问题描述 投票:0回答:1

我有一个窗口和该窗口的视图模型。在该视图模型中,我有一个名为“描述”的属性,它每秒更新一次。我还有一个名为 CustomControl 的用户控件,它有一个名为 Description 的依赖属性,该属性绑定到文本框的文本属性。我试图在我的主窗口中将该用户控件的“描述”属性绑定到用户控件的“描述”依赖项属性,但它不起作用。我在绑定上没有收到任何错误,但依赖项没有更新。相关代码见下文。

MainWindow.xaml:

<Window x:Class="DependencyBindingTest.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:DependencyBindingTest"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800">
    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>
    <Grid>
        <local:CustomControl Description="{Binding Description}" />
    </Grid>
</Window>

MainWindow.xaml.cs:

using System.Windows;

namespace DependencyBindingTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

ViewModel.cs:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace DependencyBindingTest
{
    public class ViewModel : INotifyPropertyChanged
    {
        private Random _random = new Random();

        private string _description = "asdf";

        public string Description
        {
            get { return _description; }
            set
            {
                if (_description != value)
                {
                    _description = value;
                    OnPropertyChanged();
                }
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;

        public ViewModel()
        {
            Task.Run(RunUpdateDescription);
        }

        private async Task RunUpdateDescription()
        {
            while (true)
            {
                UpdateDescription();
                await Task.Delay(1000);
            }
        }
        private async void UpdateDescription()
        {
            Description = "";

            for (int i = 0; i < 10; i++)
            {
                int random = _random.Next(65, 123);
                Char c = (Char)random;
                Description += $"{c}";
            }
        }

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

自定义控件.xaml:

<UserControl x:Class="DependencyBindingTest.CustomControl2"
             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:DependencyBindingTest"
             mc:Ignorable="d"
             d:DesignHeight="450"
             d:DesignWidth="800"
             DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}">
    <Grid >
        <local:CustomControl Description="{Binding Description}" />
    </Grid>
</UserControl>

自定义控件.xaml.cs:

using System.Windows;
using System.Windows.Controls;

namespace DependencyBindingTest
{
    /// <summary>
    /// Interaction logic for CustomControl2.xaml
    /// </summary>
    public partial class CustomControl2 : UserControl
    {
        public string Description
        {
            get { return (string)GetValue(DescriptionProperty); }
            set { SetValue(DescriptionProperty, value); }
        }

        public static readonly DependencyProperty DescriptionProperty =
       DependencyProperty.Register(
           nameof(Description),
           typeof(string),
           typeof(CustomControl2),
           new PropertyMetadata(null, OnDescriptionChanged));

        public CustomControl2()
        {
            InitializeComponent();
        }

        private static void OnDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            
        }
    }
}
c# wpf
1个回答
0
投票

您在其 xaml 中分配 UserControl 的 DataContext,因此当它评估 {Binding Desciription} 时,它会查看 UserCoontrol 而不是视图模型。这是一个常见的错误,它破坏了 WPF 对数据上下文的继承。一旦你将该 xaml 更改为:

<UserControl x:Class="DependencyBindingTest.CustomControl2"
         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:DependencyBindingTest"
         mc:Ignorable="d"
         d:DesignHeight="450"
         d:DesignWidth="800">
<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=DataContext}" >
    <local:CustomControl Description="{Binding Description}" />
</Grid>
您的代码应该一切顺利。
© www.soinside.com 2019 - 2024. All rights reserved.