【问题标题】:How to bind data in a UserControl?如何在 UserControl 中绑定数据?
【发布时间】:2013-12-28 16:35:32
【问题描述】:

这不是重复的(我希望如此)。在过去的 2 个小时里,我一直在搜索 Google 和 SO。我正在尝试将TextBlock.Text 属性绑定到我的用户控件上的一些公共属性,如下所示:

### Multimeter Overview Usercontrol Code Behind ###

public partial class MultimeterOverview : UserControl
{
    public string MeterName { get; set; }
    public int GoodPackets { get; set; }
    public int InvalidPackets { get; set; }
    public TimeSpan ElapsedTime { get; set; }
    public double MaxValue { get; set; }
    public double MinValue { get; set; }
    public double CurrentValue { get; set; }
    public string CurrentUnits { get; set; }
    public string CurrentStatus { get; set; }

    public Multimeter multimeter;
    public MainWindow program;

    public MultimeterOverview() //This method is not called...at all.
    {
        InitializeComponent();
        this.DataContext = this;
    }

    public MultimeterOverview(MainWindow reference, Multimeter multi) //This one is called
    {
        InitializeComponent();
        this.DataContext = this;
        program = reference;
        multimeter = multi;
    }
}

为简洁起见,删除了不相关的代码:

### Multimeter Overview Class XAML ###

<UserControl x:Name="Overview" x:Class="jLogger.MultimeterOverview"
         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"
         xmlns:properties="clr-namespace:jLogger.Properties"
         xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
         xmlns:d3="clr-namespace:Microsoft.Research.DynamicDataDisplay;assembly=DynamicDataDisplay"
         xmlns:d3e="clr-namespace:Microsoft.Research.DynamicDataDisplay.Charts;assembly=DynamicDataDisplay"
         mc:Ignorable="d"
         d:DesignHeight="110" d:DesignWidth="300" MinWidth="300">

           <Grid>
                <TextBlock Grid.Row="0" FontSize="20" FontFamily="Segoe UI Semilight" Margin="5, 0, 0, 0" Foreground="{StaticResource AccentColorBrush}" Text="{Binding MeterName}"/>

                <Label Grid.Row="0" Grid.Column="0" Content="Status:" Foreground="{StaticResource AccentColorBrush}" Padding="5,2,2,2"/>
                <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding ElementName=Overview, Path=CurrentStatus, Mode=TwoWay}" Foreground="Black" VerticalAlignment="Center" Margin="5, 0, 0, 0"/>

                <Label Grid.Row="1" Grid.Column="0" Content="Elapsed Time:" Foreground="{StaticResource AccentColorBrush}" Padding="5,2,2,2"/>
                <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding ElementName=Overview, Path=ElapsedTime}" Foreground="Black" VerticalAlignment="Center" Margin="5, 0, 0, 0"/>

                <Label Grid.Row="2" Grid.Column="0" Content="Good Packets:" Foreground="{StaticResource AccentColorBrush}" Padding="5,2,2,2"/>
                <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding ElementName=Overview, Path=GoodPackets}" Foreground="Black" VerticalAlignment="Center" Margin="5, 0, 0, 0"/>

                <Label Grid.Row="3" Grid.Column="0" Content="Invalid Packets:" Foreground="{StaticResource AccentColorBrush}" Padding="5,2,2,2"/>
                <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding ElementName=Overview, Path=InvalidPackets}" Foreground="Black" VerticalAlignment="Center" Margin="5, 0, 0, 0"/>
            </Grid>
    </UserControl>

此控件动态加载到ScrollViewer 内的Grid。然后我设置了MeterNameCurrentStatus 的值(两者都使用不同的绑定,试图让它工作)。但是,UI 不会更新,并且不会显示值。但是我已经通过打印MultimeterOverview.CurrentStatusMeterName 确认该值已设置,并且它们都包含正确的值。

有谁知道我怎样才能成功地将我的UserControl UI 绑定到我的UserControl?我试过了:

1. <UserControl ... DataContext="{Binding RelativeSource={RelativeSource Self}}">
2. this.DataContext = this; //In MultimeterOverview

【问题讨论】:

    标签: c# wpf xaml user-controls


    【解决方案1】:

    我怀疑你是setting the values once UserControl gets loaded

    您需要在类MultimeterOverview 上实现INotifyPropertyChanged 接口,以便UI 在类对象中的任何属性更改时得到通知。

    示例属性:

    private string meterName;
    public string MeterName
    {
       get
       {
          return meterName;
       }
       set
       {
          if(meterName != value)
          {
             meterName = value;
             OnPropertyChanged("MeterName");
          }
       }
    }
    

    您需要使其他属性遵循与上述相同的语法。

    【讨论】:

    • 我最终发现了这一点 :D 但是谢谢你的回答。以供将来参考,这是解决方案!我要注意,你可以在一行中写完:public string MeterName { get { return meterName; } set { meterName = value; OnPropertyChanged("MeterName"); } }
    • 是的,我只是想让它看起来更好看。预期的代码对我来说看起来不错。
    【解决方案2】:

    标准属性不支持绑定。您需要将属性实现为依赖属性。你的 XAML 没问题。 DataContext 需要保持不变,以便控件可以“看到”其父级的 DataContext。

    【讨论】:

    • 我对其他 UserControl 使用几乎完全相同的代码,并且它们运行良好。我怀疑这可能是由于列表框造成的?
    猜你喜欢
    • 2014-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 2014-04-30
    相关资源
    最近更新 更多