如何绑定UserControl中的数据?

时间:2013-12-28 06:20:22

标签: c# wpf xaml user-controls

这不是重复(我希望)。我花了最近2个小时搜索谷歌和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>

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

有谁知道我如何成功地将UserControl UI绑定到UserControl?我试过了:

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

2 个答案:

答案 0 :(得分: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");
      }
   }
}

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

答案 1 :(得分:0)

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