WPF 数据绑定问题

发布于 2024-10-28 12:08:39 字数 2855 浏览 1 评论 0原文

我一直在用头撞墙,觉得是时候提出一个问题了。我有以下用户控件

XAML

<UserControl x:Class="WorkDayManager3.WPF.UserControls.TimeControl"
         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="46" d:DesignWidth="133" Background="Transparent"
         DataContext="{Binding RelativeSource={RelativeSource self}}">    
<Grid Height="44" Width="132" Background="Transparent">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="29" />            
    </Grid.ColumnDefinitions>

    <TextBox Name="label" Text="{Binding Text}" Grid.ColumnSpan="5"></TextBox>

</Grid>

C#

public partial class TimeControl : UserControl
{
    public string Text
    {

        get { return (string)GetValue(TextProperty); }

        set { SetValue(TextProperty, value); }

    }

    // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...

    public static readonly DependencyProperty TextProperty =

    DependencyProperty.Register("Text", typeof(string), typeof(TimeControl), new UIPropertyMetadata("N/A"));

    public TimeControl()
    {
        InitializeComponent();
    }

在我使用该控件的窗口中,它在网格中使用,其数据上下文设置为 StaticResource

    <Grid Grid.Row="1" HorizontalAlignment="Center" DataContext="{StaticResource shiftViewSource}" Name="grid1" Margin="48,10,38,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBox Grid.Column="0" Grid.Row="1" Height="23" TabIndex="2" HorizontalAlignment="Left" Margin="10,5,0,5" Name="shiftNameTextBox" Text="{Binding Path=ShiftName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
        <my2:TimeControl Grid.Column="0" Grid.Row="2" Height="23" TabIndex="2" HorizontalAlignment="Left" Margin="10,5,0,5" Name="shiftNameTextBox" Text="{Binding Path=ShiftName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
        <my2:TimeControl Grid.Column="0" Grid.Row="3" Text="THIS WORKS OK"/>            
    </Grid>

现在,绑定到 Path ShiftName 的 TextBox 工作正常并显示文本。当我使用我的控件时,它不会显示预期的文本。但是,在第二个示例中,我只是将文本依赖属性设置为“THIS WORKS OK”,文本按预期显示。为什么绑定对 TextBox 有效,但对我的控件无效。我做错了什么?

Been beating my head against a wall and figured it was time to post a question. I have the following user control

XAML

<UserControl x:Class="WorkDayManager3.WPF.UserControls.TimeControl"
         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="46" d:DesignWidth="133" Background="Transparent"
         DataContext="{Binding RelativeSource={RelativeSource self}}">    
<Grid Height="44" Width="132" Background="Transparent">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="29" />            
    </Grid.ColumnDefinitions>

    <TextBox Name="label" Text="{Binding Text}" Grid.ColumnSpan="5"></TextBox>

</Grid>

C#

public partial class TimeControl : UserControl
{
    public string Text
    {

        get { return (string)GetValue(TextProperty); }

        set { SetValue(TextProperty, value); }

    }

    // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...

    public static readonly DependencyProperty TextProperty =

    DependencyProperty.Register("Text", typeof(string), typeof(TimeControl), new UIPropertyMetadata("N/A"));

    public TimeControl()
    {
        InitializeComponent();
    }

In the Window where i use the control it is used in a grid with its datacontext set to a StaticResource

    <Grid Grid.Row="1" HorizontalAlignment="Center" DataContext="{StaticResource shiftViewSource}" Name="grid1" Margin="48,10,38,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <TextBox Grid.Column="0" Grid.Row="1" Height="23" TabIndex="2" HorizontalAlignment="Left" Margin="10,5,0,5" Name="shiftNameTextBox" Text="{Binding Path=ShiftName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
        <my2:TimeControl Grid.Column="0" Grid.Row="2" Height="23" TabIndex="2" HorizontalAlignment="Left" Margin="10,5,0,5" Name="shiftNameTextBox" Text="{Binding Path=ShiftName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
        <my2:TimeControl Grid.Column="0" Grid.Row="3" Text="THIS WORKS OK"/>            
    </Grid>

Now the TextBox that is Bound to Path ShiftName works fine and displays the text. When i use my control instead it doesn't show the expected text. However in the second example where i just set the Text dependency property to "THIS WORKS OK" the text shows up as expected. Why does the binding work for the TextBox but not my control. What am i doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乖乖公主 2024-11-04 12:08:39

您已将 UserControl 上的 DataContext 设置为自身。因此,TimeControlText 属性的绑定尝试在 TimeControl 上查找名为 ShiftName 的属性,不在您的静态资源上。如果您查看 Visual Studio 的输出窗口,您应该会看到一条错误消息。

无论如何,在 UserControl 上设置 DataContext 从来都不是一个好主意,因为任何人都可以覆盖它。你可以这样做:

<UserControl x:Name="root" ...>
    <Grid DataContext="{Binding ElementName=root}"
        ...

You've set the DataContext on the UserControl to itself. Thus, the binding of your TimeControl's Text property is attempting to find a property called ShiftName on your TimeControl, not on your static resource. If you look in the output window of visual studio, you should see an error message to that effect.

It is never a good idea to set the DataContext on the UserControl anyway, because anyone could override it. You could just do this instead:

<UserControl x:Name="root" ...>
    <Grid DataContext="{Binding ElementName=root}"
        ...
静赏你的温柔 2024-11-04 12:08:39

另一种方法可能是使用相对绑定:

<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" >
    ...

An other way might be to use a Relative binding:

<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" >
    ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文