简体   繁体   中英

How to bind data in a UserControl?

This is not a duplicate (I hope). I have spent the last 2 hours searching both Google and SO to to avail. I am trying to bind the TextBlock.Text property to some public properties on my user control, as shown below:

### 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;
    }
}

And with irrelevant code removed for brevity:

### 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>

This control is dynamically loaded into a Grid inside a ScrollViewer . I then set the value of both the MeterName and CurrentStatus (Both of which are using different bindings, in an attempt to try and get it working). However, the UI does not update, and the values are not displayed. However I have confirmed that the value gets set, by printing the MultimeterOverview.CurrentStatus and MeterName , and they both contain the correct values.

Does anyone know how I can successfully bind my UserControl UI to my UserControl ? I have tried:

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

I suspect you are setting the values once UserControl gets loaded .

You need to implement INotifyPropertyChanged interface on class MultimeterOverview so that UI gets notified on any property change in class object.

Sample property:

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

You need to make other properties to follow the same syntax like mentioned above.

Standard properties do not support binding. You need implement your properties as dependency properties. Your XAML is ok. The DataContext needs to be untouched so that the control can "see" the DataContext of its parent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM