Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何为绑定正确设置WPF UserControl_C#_Wpf_Binding - Fatal编程技术网

C# 如何为绑定正确设置WPF UserControl

C# 如何为绑定正确设置WPF UserControl,c#,wpf,binding,C#,Wpf,Binding,我想创建一个UserControl,它本质上是一个带有文本框的标签。现在我想能够将TextBox.Text绑定到不同的值 为此,我在UserControl中创建了DependencyProperty,现在正尝试将某些内容绑定到新创建的DependencyProperty,但文本似乎没有得到更新 我的UserControl1.xaml如下所示: <UserControl x:Class="WpfApplication1.UserControl1" xmlns="http:/

我想创建一个UserControl,它本质上是一个带有文本框的标签。现在我想能够将
TextBox.Text
绑定到不同的值

为此,我在UserControl中创建了DependencyProperty,现在正尝试将某些内容绑定到新创建的DependencyProperty,但文本似乎没有得到更新

我的UserControl1.xaml如下所示:

<UserControl x:Class="WpfApplication1.UserControl1"
         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" 
         mc:Ignorable="d" 
         d:DesignHeight="48" d:DesignWidth="200">
<Grid>
    <WrapPanel Height="48" HorizontalAlignment="Left" Name="wrapPanel1" VerticalAlignment="Top" Width="200">
        <Label Content="Label" Height="48" Name="label1" Width="100" />
        <TextBox Height="48" Name="textBox1" Width="100"  />
    </WrapPanel>
</Grid>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using System.Diagnostics;

namespace WpfApplication1
{


    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        private string value;
        public string Value
        {
            get { return value; }
            set
            {
                this.value = value;
                textBox1.Text = value;
                Trace.TraceInformation("value set in UserControl1");
            }
        }
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(string), typeof(UserControl1));
        public UserControl1()
        {
            InitializeComponent();
        }
    }
}
<my:UserControl1 x:Name="userControl11" Value="{Binding Path=Name}" />

我的UserControl1.xaml.cs如下所示:

<UserControl x:Class="WpfApplication1.UserControl1"
         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" 
         mc:Ignorable="d" 
         d:DesignHeight="48" d:DesignWidth="200">
<Grid>
    <WrapPanel Height="48" HorizontalAlignment="Left" Name="wrapPanel1" VerticalAlignment="Top" Width="200">
        <Label Content="Label" Height="48" Name="label1" Width="100" />
        <TextBox Height="48" Name="textBox1" Width="100"  />
    </WrapPanel>
</Grid>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using System.Diagnostics;

namespace WpfApplication1
{


    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        private string value;
        public string Value
        {
            get { return value; }
            set
            {
                this.value = value;
                textBox1.Text = value;
                Trace.TraceInformation("value set in UserControl1");
            }
        }
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(string), typeof(UserControl1));
        public UserControl1()
        {
            InitializeComponent();
        }
    }
}
<my:UserControl1 x:Name="userControl11" Value="{Binding Path=Name}" />
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
使用系统诊断;
命名空间WpfApplication1
{
/// 
///UserControl1.xaml的交互逻辑
/// 
公共部分类UserControl1:UserControl
{
私有字符串值;
公共字符串值
{
获取{返回值;}
设置
{
这个值=值;
textBox1.Text=值;
Trace.TraceInformation(“UserControl1中设置的值”);
}
}
公共静态只读从属属性ValueProperty=
Register(“Value”、typeof(string)、typeof(UserControl1));
公共用户控制1()
{
初始化组件();
}
}
}
我使用的UserControl如下所示:

<UserControl x:Class="WpfApplication1.UserControl1"
         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" 
         mc:Ignorable="d" 
         d:DesignHeight="48" d:DesignWidth="200">
<Grid>
    <WrapPanel Height="48" HorizontalAlignment="Left" Name="wrapPanel1" VerticalAlignment="Top" Width="200">
        <Label Content="Label" Height="48" Name="label1" Width="100" />
        <TextBox Height="48" Name="textBox1" Width="100"  />
    </WrapPanel>
</Grid>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using System.Diagnostics;

namespace WpfApplication1
{


    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        private string value;
        public string Value
        {
            get { return value; }
            set
            {
                this.value = value;
                textBox1.Text = value;
                Trace.TraceInformation("value set in UserControl1");
            }
        }
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(string), typeof(UserControl1));
        public UserControl1()
        {
            InitializeComponent();
        }
    }
}
<my:UserControl1 x:Name="userControl11" Value="{Binding Path=Name}" />


DataContext
设置为具有Name属性并为此属性实现INotifyPropertyChanged的对象。

将TextBox的文本和UserControl的值之间的连接放在错误的位置。CLR属性用于方便,但绑定引擎不使用它。您需要在XAML或代码隐藏上显式地将TextBox的文本绑定到Usercontrol的值,例如(假设您给用户控件一个名为root):


您将TextBox文本和UserControl值之间的连接放在了错误的位置。CLR属性用于方便,但绑定引擎不使用它。您需要在XAML或代码隐藏上显式地将TextBox的文本绑定到Usercontrol的值,例如(假设您给用户控件一个名为root):


对于包装依赖项属性的属性,不能向getset访问器添加其他逻辑或代码。它不会被执行

这样做的原因是,WPF设计器将实际生成直接使用DependencyProperty的代码。get/set属性只是为了方便您在代码中使用它。因为您希望DependencyProperty和属性的get/set执行相同的操作,所以在传入相关的dependency属性时,应该只调用get/set访问器中的GetValue和SetValue

请参阅以下教程:


对于包装依赖项属性的属性,不能向getset访问器添加其他逻辑或代码。它不会被执行

这样做的原因是,WPF设计器将实际生成直接使用DependencyProperty的代码。get/set属性只是为了方便您在代码中使用它。因为您希望DependencyProperty和属性的get/set执行相同的操作,所以在传入相关的dependency属性时,应该只调用get/set访问器中的GetValue和SetValue

请参阅以下教程:


看看这个实现。它使用非常简单的MVVM设计来获得数据绑定。 基本上这就是它所做的:

  • 您拥有将其DataContext设置为相应ViewModel的UserControl(视图)
  • 然后,视图上的文本框将绑定到该ViewModel中的公共属性
  • 通过实现INotifyPropertyChanged,您可以使ViewModel在更改文本属性的值时有效地更新UI
这可以对任意数量的绑定重复,并应用于许多不同的类型,如列表、ObservableCollections和整数

查看

<UserControl x:Class="WpfApplication1.UserControl1"
         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" 
         mc:Ignorable="d" d:DesignHeight="48" d:DesignWidth="200">
<Grid>
    <WrapPanel Height="48" HorizontalAlignment="Left" Name="wrapPanel1" VerticalAlignment="Top" Width="200">
        <Label Content="Label" Height="48" Name="label1" Width="100" />
        <TextBox Height="48" Name="textBox1" Width="100" Text={Binding Text} />
    </WrapPanel>
</Grid>
视图模型

namespace WpfApplication1
{
    using System.Collections.ObjectModel;
    using System.Windows.Controls;

    class UserControl1ViewModel : INotifyPropertyChanged
    {
        // Ultimately, this field (text) would be moved to a model along with 
        // any other data fields for this view but for the sake of space, 
        // I've put it in the ViewModel.
        private string text = "";
        public string Text 
        { 
            get { return text; } 
            set 
            { 
                text = value;
                RaisePropertyChanged("Text");
            } 
        }

        public MainWindowViewModel()
        {
            Text = "Hello!";
        }

        // This is the implementation of INotifyPropertyChanged that is used 
        // to inform the UI of changes.
        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

祝你好运

看看这个实现。它使用非常简单的MVVM设计来获得数据绑定。 基本上这就是它所做的:

  • 您拥有将其DataContext设置为相应ViewModel的UserControl(视图)
  • 然后,视图上的文本框将绑定到该ViewModel中的公共属性
  • 通过实现INotifyPropertyChanged,您可以使ViewModel在更改文本属性的值时有效地更新UI
这可以对任意数量的绑定重复,并应用于许多不同的类型,如列表、ObservableCollections和整数

查看

<UserControl x:Class="WpfApplication1.UserControl1"
         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" 
         mc:Ignorable="d" d:DesignHeight="48" d:DesignWidth="200">
<Grid>
    <WrapPanel Height="48" HorizontalAlignment="Left" Name="wrapPanel1" VerticalAlignment="Top" Width="200">
        <Label Content="Label" Height="48" Name="label1" Width="100" />
        <TextBox Height="48" Name="textBox1" Width="100" Text={Binding Text} />
    </WrapPanel>
</Grid>
视图模型

namespace WpfApplication1
{
    using System.Collections.ObjectModel;
    using System.Windows.Controls;

    class UserControl1ViewModel : INotifyPropertyChanged
    {
        // Ultimately, this field (text) would be moved to a model along with 
        // any other data fields for this view but for the sake of space, 
        // I've put it in the ViewModel.
        private string text = "";
        public string Text 
        { 
            get { return text; } 
            set 
            { 
                text = value;
                RaisePropertyChanged("Text");
            } 
        }

        public MainWindowViewModel()
        {
            Text = "Hello!";
        }

        // This is the implementation of INotifyPropertyChanged that is used 
        // to inform the UI of changes.
        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

祝你好运

我试过了,这使得我的userControl得到了更新,但现在我似乎有了一个不同的错误:每当我更改
userControl11.TextBox1.Text
时,当绑定数据再次更改时,它不会得到更新。我尝试将
Text=“{Binding Path=Value,ElementName=root,Mode=TwoWay}”
放在文本框中,但这对Eithter没有帮助。这很棘手。默认情况下,如果在使用自定义依赖项属性时未指定BindingMode,则该属性为单向绑定。您有两个选择,一个是在使用时指定Mode=TwoWay,第二个是覆盖FrameworkPropertyMetadata以指定默认绑定模式为TwoWay。我尝试了这一点,这使我的userControl得到更新,但现在我似乎有了一个不同的错误:每当我更改
userControl11.TextBox1.Text时,它不会得到更新,而我的