【问题标题】:How to force datasource to be updated from TemplateControl如何强制从 TemplateControl 更新数据源
【发布时间】:2011-12-23 21:42:51
【问题描述】:

我解决了一个简单的问题就搞砸了。我有一个带有填充模板属性的自定义控件。该模板是一个简单的 Grid,里面有一个 TextBox。此文本框使用 setter 和 getter 绑定到单例的属性。如何以编程方式强制 TextBox 从单例中读取值并将其放回?

<Window x:Class="Spike.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="305" Width="521" xmlns:my="clr-namespace:Spike" xmlns:Data="clr-namespace:Spike.Data">
    <Grid>
        <Grid.Resources>
            <ControlTemplate x:Key="editingTemplate">
                <Grid>
                    <TextBox Text="{Binding Source={x:Static Data:MyClass.Instance}, Path=Value2}"/>
                </Grid>
            </ControlTemplate>
        </Grid.Resources>

        <UserControl Template="{StaticResource editingTemplate}" HorizontalAlignment="Left" Margin="58,60,0,0" x:Name="myUserControl1" VerticalAlignment="Top" Height="75" Width="284" />
        <Button Content="Update source" Height="23" HorizontalAlignment="Left" Margin="184,23,0,0" Name="button1" VerticalAlignment="Top" Width="111" Click="button1_UpdateSource" Focusable="False" />
        <Button Content="Update control" Focusable="False" Height="23" HorizontalAlignment="Left" Margin="58,23,0,0" Name="button2" VerticalAlignment="Top" Width="111" Click="button2_UpdateControl" />
    </Grid>
</Window>
namespace Spike.Data
{
    public class MyClass
    {
        private static readonly MyClass MyClassInstance = new MyClass();

        public MyClass()
        {
            Value1 = "value1";
            Value2 = "value2";
        }

        public static MyClass Instance
        {
            get { return MyClassInstance; }
        }

        public string Value1 { get; set; }

        public string Value2 { get; set; }
    }
}

换句话说,应该在 button2_UpdateControlbutton1_UpdateSource 方法中实现什么?

提前感谢您的帮助

【问题讨论】:

    标签: wpf data-binding controltemplate


    【解决方案1】:

    不应手动重新调用绑定。相反,您应该尝试使当前的 Binding 机制正常工作。 您的 TextBox 应该绑定到 DependancyProperty 或者 TextBox 的 DataContext 应该实现 INotifyPropertyChanged。 像这样定义您的 Value2 属性:

    public static readonly DependencyProperty Value2Property = 
        DependencyProperty.Register("Value2", typeof(string), typeof(MyClass), new PropertyMetadata(string.Empty));
    
    public string Value2
    {
        get { return (string)GetValue(Value2Property); }
        set { SetValue(Value2Property, value); }
    }
    

    另外,MyClass 应该实现 UIElement。

    【讨论】:

    • MyClass 可以实现 INotifyPropertyChanged - 这不是问题。但我想了解在没有任何关于其模板的知识的情况下的 UserControl 如何强制绑定对象中的 TextBox 更新值。
    • UserControl 不强制 TextBox 更新。 TextBox 绑定到事件并响应这些事件,这就是更新 TextBox 的内容。 UserControl 不知道也不关心 TextBox 绑定到什么。它只是作为容器(在您的场景中)到其他可以具有单独绑定上下文的控件。
    • 好的,假设用户控件是网格中的一个单元格,可以有多个模板: 1. 一个处于正常状态。 2.数据编辑时的另一个模板。当用户单击一个单元格时,网格会更改模板。在设置新模板时,它会从数据对象中获取一个值。当编辑控件失去焦点时 - 它会尝试通过一些验证过程调用属性的设置器。是否可以强制此控件以编程方式提交修改后的值而不会失去焦点?
    • 一切皆有可能,您只需要了解 DataContext、触发器和绑定是如何工作的。如果您正确设置所有内容,则可以实现您想要的。但是,如果没有确切的代码,我无法告诉您比您具体要求的更多信息。
    • 我提供的代码与我的真实示例非常接近。文本框一开始就得到一个值,但是我不明白如何实现button1_UpdateSource()。如果将 button1.Focusable 设置为 true,则当用户单击按钮时,它会获得焦点,因此 TextBox 会更新绑定对象中的值。我的问题:如何在不改变焦点的情况下以编程方式进行操作?
    猜你喜欢
    • 2023-01-26
    • 2020-04-14
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 2021-08-03
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    相关资源
    最近更新 更多