gpt4 book ai didi

c# - UserControl 具有传播到内部控件的绑定(bind)

转载 作者:行者123 更新时间:2023-12-03 10:29:44 27 4
gpt4 key购买 nike

这可能不是一个火箭科学问题,所以请原谅我是一个新人!
我有一个用于设置人名的 UserControl(简单用于测试目的)。

PersonNameControl.xaml:

<UserControl x:Class="BindingPropagationTest.Controls.PersonNameControl"
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" Width="120" Height="23" Margin="0,0,0,0"
>
<TextBox Name="TextBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</UserControl>

如您所见,它包含一个 TextBox,它是“真正的”文本框。后面的代码是这样的。

PersonNameControl.xaml.cs:
using System.Windows.Controls;
using System.Windows;
using System.Diagnostics;

namespace BindingPropagationTest.Controls
{
public partial class PersonNameControl : UserControl
{
public static DependencyProperty nameProperty
= DependencyProperty.Register("PersonName", typeof(string), typeof(PersonNameControl));

public string PersonName
{
get
{
Debug.WriteLine("get PersonNameControl.PersonName = " + TextBox.Text);
return TextBox.Text;
}

set
{
Debug.WriteLine("set PersonNameControl.PersonName = " + value);
TextBox.Text = value;
}
}

public PersonNameControl()
{
InitializeComponent();
}
}
}

我在 MainWindow.xaml 中使用用户控件:
<Window x:Class="BindingPropagationTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:BindingPropagationTest.Controls"
xmlns:items="clr-namespace:BindingPropagationTest.ComboBoxItems"
Title="Testing binding in UserControl"
Width="179" Height="310">
<Canvas Height="241" Width="144">

<Label Canvas.Left="11" Canvas.Top="10" Content="Name" Height="28" Padding="0" />
<my:PersonNameControl x:Name="nameControl"
Width="120" Height="23"
HorizontalAlignment="Left" VerticalAlignment="Top"
PersonName="{Binding name}"
Canvas.Left="11" Canvas.Top="28" />

<Label Canvas.Left="11" Canvas.Top="57" Content="Address" Height="28" Padding="0" />
<TextBox Canvas.Left="11" Canvas.Top="75" Width="120" Text="{Binding address}"></TextBox>

<Label Canvas.Left="11" Canvas.Top="103" Content="Age" Height="28" Padding="0" />
<TextBox Canvas.Left="11" Canvas.Top="122" Height="23" Name="textBox1" Width="120" Text="{Binding age}" />

<ComboBox Canvas.Left="11" Canvas.Top="173" Height="23"
Name="comboBox1" Width="120" SelectionChanged="comboBox1_SelectionChanged">
<items:PersonComboBoxItem age="41" name="Donald Knuth" address="18 Donut Street" Height="23" />
<items:PersonComboBoxItem age="23" name="Vladimir Putin" address="15 Foo Street" Height="23" />
<items:PersonComboBoxItem age="32" name="Mike Hammer" address="10 Downing Street" Height="23" />
</ComboBox>
</Canvas>
</Window>

如您所见,还有一些普通的文本框。

在 MainWindow 后面的代码中

MainWindow.xaml.cs:
using System.Windows;
using System.Windows.Controls;
using BindingPropagationTest.ComboBoxItems;

namespace BindingPropagationTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Person();
}

private void comboBox1_SelectionChanged
(object sender, SelectionChangedEventArgs e)
{
updateForm();
}

private void updateForm()
{
var item = (PersonComboBoxItem)comboBox1.SelectedItem;

DataContext = new Person()
{ age = item.age, name = item.name, address = item.address };
}
}
}

您会看到我将 DataContext 设置为“人”。

个人.cs:
namespace BindingPropagationTest
{
public class Person
{
public string name {get; set; }
public int age { get; set; }
public string address { get; set; }
}
}

正如你所注意到的,我发明了一个像这样的自己的 ComboBoxItem。
PersonComboBoxItem.cs:
using System.Windows.Controls;
using System.Diagnostics;

namespace BindingPropagationTest.ComboBoxItems
{
public class PersonComboBoxItem : ComboBoxItem
{
private string _name = "";
public string name
{
get
{
return _name;
}
set
{
_name = value;
Content = _name;
}
}

public int age { get; set; }
public string address { get; set; }

public override string ToString()
{
Debug.WriteLine("name: " + name);
return name;
}
}
}

运行这个应用程序会给你这个窗口:

enter image description here

并选择一个组合框项目给你这个:

enter image description here

如您所见,名称不会被填写。
为什么不?

最佳答案

你快到了,你需要改变一些事情

依赖属性的使用方式如下

    public static DependencyProperty NameProperty = DependencyProperty.Register(
"Name",
typeof(string),
typeof(PersonNameControl));

public string Name
{
get
{
return (string)GetValue(NameProperty);
}
set
{
SetValue(NameProperty, value);
}
}

依赖属性有一个非常严格的约定。如果属性称为名称,则必须将其称为“名称属性”。该属性也只是设置并获取依赖属性。

您可以将文本框绑定(bind)到用户控件中的属性,例如
<UserControl x:Class="BindingPropagationTest.Controls.PersonNameControl"
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"
x:Name="UserControl"
mc:Ignorable="d" Width="120" Height="23" Margin="0,0,0,0"
>
<TextBox Text="{Binding ElementName=UserControl, Path=Name}" Name="TextBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</UserControl>

我在顶部添加了 x:Name="UserControl"指令,您可以将其命名为任何名称,只要它与 Binding 中的 ElementName 匹配即可

关于如何填充组合框的额外说明

您可以在 MainWindow 上添加一个属性
    private ObservableCollection<Person> _thePeople;
public ObservableCollection<Person> ThePeople
{
get
{
if (_thePeople == null)
{
List<Person> list = new List<Person>()
{
new Person() { name = "Bob" , address = "101 Main St." , age = 1000 },
new Person() { name = "Jim" , address = "101 Main St." , age = 1000 },
new Person() { name = "Mip" , address = "101 Main St." , age = 1000 },
};
_thePeople = new ObservableCollection<Person>(list);
}
return _thePeople;
}
}

然后您可以将用户控件上使用的 x:Name 指令添加到主窗口中
x:Name="TheMainWindow"

然后,您可以在组合框中使用数据模板,如下所示
    <ComboBox ItemsSource="{Binding ElementName=TheMainWindow, Path=ThePeople}"
Height="23"
Name="comboBox1" Width="120" >
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding name}" />
<TextBlock Text="{Binding address}" />
<TextBlock Text="{Binding age}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

因为在代码隐藏中使用了 ObservableCollection,所以每当代码隐藏从“ThePeople”集合中添加或删除项目时,组合框将自动获取添加或删除的项目。打电话
ThePeople.Add(new Person());

并且组合框将自动填充一个新条目

关于c# - UserControl 具有传播到内部控件的绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11332665/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com