【问题标题】:Two way binding use a user control...binding to object, not an element?两种方式绑定使用用户控件...绑定到对象,而不是元素?
【发布时间】:2011-02-23 01:52:55
【问题描述】:

我创建了一个带有默认值的简单属性的对象。然后我创建了一个用户控件,其中包含一个文本框。我将用户控件的数据上下文设置为对象。

文本框正确显示属性默认值,但当用户更改文本框值时,我似乎无法更新属性值。我创建了一个简单的项目来说明我的代码。

感谢您的帮助!

public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        private string _titleValue;

        public string TitleValue
        {
            get
            {
                return _titleValue;
            }
            set 
            {
                _titleValue = value;
                textBox1.Text = _titleValue;
            }
        }

        public static readonly DependencyProperty TitleValueProperty = DependencyProperty.Register(
           "TitleValue", typeof(string), typeof(UserControl1), new FrameworkPropertyMetadata(new PropertyChangedCallback(titleUpdated))
           );

//Don't think I should need to do this!!!
        private static void titleUpdated(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((UserControl1)d).TitleValue = (string)e.NewValue; 
        }
    }

<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="300" d:DesignWidth="300">
    <Grid>
        <TextBox Height="23" HorizontalAlignment="Left" Margin="94,97,0,0" Name="textBox1" VerticalAlignment="Top" Width="120"
                  Text="{Binding Path=TitleValue, Mode=TwoWay}"/>
    </Grid>
</UserControl>

    public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();

                var dummy = new DummyObject("This is my title.");
                userControl11.DataContext = dummy;

            }

            private void button1_Click(object sender, RoutedEventArgs e)
            {
                MessageBox.Show("The value is: " + ((DummyObject)userControl11.DataContext).Title);
            }
        }

    <Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:WpfApplication1">
        <Grid>
            <my:UserControl1 HorizontalAlignment="Left" Margin="95,44,0,0" x:Name="userControl11" VerticalAlignment="Top" Height="191" Width="293" 
                             TitleValue="{Binding Path=Title, Mode=TwoWay}"/>
            <Button Content="Check Value" Height="23" HorizontalAlignment="Left" Margin="20,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
        </Grid>
    </Window>

【问题讨论】:

    标签: wpf binding binding-mode


    【解决方案1】:

    您的用户控件上的DataContext 未设置。为其指定一个Name(我通常称我的“ThisControl”)并将TextBox 的绑定修改为Text="{Binding ElementName=ThisControl, Path=TitleValue, Mode=TwoWay}"。您也可以显式设置DataContext,但我相信这是首选方式。

    似乎默认的DataContext应该是“this”,但默认情况下什么都没有。

    [编辑] 您可能还想将 , UpdateSourceTrigger=PropertyChanged 添加到您的绑定中,因为默认情况下,TextBoxes 的文本绑定仅在失去焦点时更新。

    【讨论】:

    • 我不是想装傻(虽然这很难!)但我没有在这行代码(MainWindow)中设置它: var dummy = new DummyObject("This is my title ."); userControl11.DataContext = 虚拟;我在哪里设置?
    • 我不怪你,WPF 的初始学习曲线相当陡峭。你设置的DataContext是给UserControl1的那个实例的,但我说的是UserControl1的的DataContext,没有设置。在您拥有 d:DesignHeight="300" d:DesignWidth="300"> 的顶部,将“Name="ThisControl"” 添加到它(或您喜欢的任何名称)。然后对我上面提到的绑定进行修改。
    • 好吧,那行得通。非常感谢!!!好的,最后一个问题。假设我创建了另一个包含 UserControl1 的用户控件,我们称之为 UserControl2。然后我将 UserControl2 放在 MainWindow 上,并将它的 datacontext 设置为虚拟对象。我需要在 UserControl2 上添加依赖属性吗?抱歉这些问题......
    • 更明确地说,我认为数据绑定在控制树上下工作。我希望 UserControl1 仍然能够绑定相同的属性并让它双向工作......但事实并非如此。一旦我将 UserControl1 放到 UserControl2 中,然后将 UserControl2 放到 MainWindow 绑定就被破坏了。再次感谢!
    • 我想通了......或者至少我让它与两层用户控制一起工作。我从绑定中删除了 ElementName 并按照您的建议添加了 UpdateSourceTrigger=PropertyChanged 。现在可以了,我不知道为什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多