如何正确设置绑定的WPF UserControl
本文关键字:WPF UserControl 绑定 何正确 设置 | 更新日期: 2023-09-27 18:25:52
我想创建一个UserControl,它本质上是一个带有TextBox的Label。现在我希望能够将TextBox.Text
绑定到不同的值。
为此,我在UserControl中创建了一个DependencyProperty,现在正试图将某些内容绑定到新创建的DependencyProperties,但文本似乎没有更新。
我的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>
我的UserControl1.xaml.cs看起来是这样的:
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();
}
}
}
我使用的UserControl是这样的:
<my:UserControl1 x:Name="userControl11" Value="{Binding Path=Name}" />
CCD_ 2设置为具有Name属性并为此属性实现INotifyPropertyChanged的对象。
您将TextBox的Text和UserControl的Value之间的连接放错了位置。CLR属性是为了方便而使用的,但绑定引擎不使用它。您需要在XAML或代码背后显式地将TextBox的Text绑定到Usercontrol的Value,例如(假设您为用户控件提供了一个名为root的名称):
<TextBox x:Name="textBox1" Text="{Binding Path=Value, ElementName=root}"/>
对于包装依赖属性的属性,不能向get或set访问器添加额外的逻辑或代码。它不会被执行。
原因是WPF设计器实际上会生成直接使用DependencyProperty的代码。get/set属性只是为了方便您在代码中使用它。因为您希望DependencyProperty和属性的get/set做同样的事情,所以在传入相关的依赖项属性时,应该只调用get/set访问器中的GetValue和SetValue。
请参阅以下教程:
依赖项属性依赖属性概述
看看这个实现。它使用一个非常简单的MVVM设计来获得数据绑定。基本上这就是它正在做的:
- 您有一个UserControl(视图),它将它的DataContext设置为相应的ViewModel
- 然后,视图上的TextBox绑定到该ViewModel中的公共属性
- 通过实现INotifyPropertyChanged,您可以使ViewModel在更改Text属性值时有效地更新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.Windows;
using System.Windows.Controls;
public partial class UserControl1: UserControl
{
public UserControl1()
{
DataContext = new UserControl1ViewModel();
InitializeComponent();
}
}
}
ViewModel
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));
}
}
}
祝你好运!