Marty
Marty

Reputation: 73

Dependency property not binding to view

what im tryin to do is populate a combobox based upon the selected item of a treeview. as depending on what node is chosen will populate the combobox with a different list of report levels.

the combobox is within a user control and i am trying to bind to a dependency property ReportLevel i have in my MainViewModel. if i set the value of the combobox its fine but i want to be able to update it whenever a user choses a different node on the tree.

here is my xaml

    <UserControl x:Name="this"
    x:Class="RTHM.ComboboxControl1"
         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" 
         xmlns:local ="clr-namespace:RTHM.ViewModels"
         d:DesignHeight="300" d:DesignWidth="300">

<Grid>
    <StackPanel HorizontalAlignment="Center" MinHeight="221.904" Margin="12,12,42,0" VerticalAlignment="Top" MaxWidth="246.226" Width="246">
        <WrapPanel HorizontalAlignment="Left" MinHeight="224.072" VerticalAlignment="Top" MinWidth="246.13">
            <TextBox HorizontalAlignment="Left" MinHeight="104.489" Margin="10,289.95,0,0" TextWrapping="Wrap" Text="{Binding ReportDescription, Mode=TwoWay}" VerticalAlignment="Top" MinWidth="245.124"/>
            <TextBox MinHeight="23" TextWrapping="Wrap" Text="Report Level:" MinWidth="120" BorderThickness="1" Margin="0,0,5,5"/>
            <ComboBox MinWidth="120" Margin="0,0,0,5" MinHeight="23" 

                      ItemsSource="{Binding ElementName=this, Path=ReportLevel,Mode=TwoWay}" 
                      IsSynchronizedWithCurrentItem="True"
                      DisplayMemberPath="Name" 
                      SelectedItem="{Binding Path=SelectedLevel, Mode=TwoWay}"
                      IsEnabled="{Binding IsEnabled}"/>

my code behind

public partial class ComboboxControl1 : UserControl
{
    public ComboboxControl1()
    {
        InitializeComponent();

       DataContext = new MainViewModel();

in my MainViewModel i have this

    #region DependencyProperties
   public static readonly DependencyProperty LevelProperty =
       DependencyProperty.Register("ReportLevel",typeof(ObservableCollection<ReportLevel>),typeof(MainViewModel));

    public ObservableCollection<ReportLevel> ReportLevel
   {
       get
       {
           return (ObservableCollection<ReportLevel>)GetValue(LevelProperty);
       }
       set
       {
           SetValue(LevelProperty, value);
       }
   }

and have a method which sets the value of this like

            ReportLevel = c.GetUserReportLevel();

i have tried various things with the ItemSource of the combobox but without success.

Any help on the matter would be appreciated

Thanks, Marty EDIT: Have updated my code but still no luck with this matter, any ideas? Xaml

<UserControl x:Class="RTHM.ComboboxControl1"
         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" 
         xmlns:local ="clr-namespace:RTHM.ViewModels"
         d:DesignHeight="300" d:DesignWidth="300">

<Grid>
    <StackPanel HorizontalAlignment="Center" MinHeight="221.904" Margin="12,12,42,0" VerticalAlignment="Top" MaxWidth="246.226" Width="246">
        <WrapPanel HorizontalAlignment="Left" MinHeight="224.072" VerticalAlignment="Top" MinWidth="246.13">
            <TextBox HorizontalAlignment="Left" MinHeight="104.489" Margin="10,289.95,0,0" TextWrapping="Wrap" Text="{Binding ReportDescription, Mode=TwoWay}" VerticalAlignment="Top" MinWidth="245.124"/>
            <TextBox MinHeight="23" TextWrapping="Wrap" Text="Report Level:" MinWidth="120" BorderThickness="1" Margin="0,0,5,5"/>
            <ComboBox MinWidth="120" Margin="0,0,0,5" MinHeight="23" 

                      ItemsSource="{Binding Path=Levels}" 
                      IsSynchronizedWithCurrentItem="True"
                      DisplayMemberPath="Name" 
                      SelectedItem="{Binding Path=SelectedLevel, Mode=TwoWay}"
                      IsEnabled="{Binding IsEnabled}"/>

and in MainViewModel

private ObservableCollection<ReportLevel> _levels;
public ObservableCollection<ReportLevel> Levels
    {
        get
        {
            return _levels;
        }
        set
        {
            _levels = value;
            NotifyPropertyChanged("Levels");
        }
    }

my MainViewModel inherits from a base class which has INotifyProperty changed and an implementation

public class ViewModelBase :  INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Upvotes: 0

Views: 86

Answers (1)

Clemens
Clemens

Reputation: 128136

The binding

ItemsSource="{Binding ElementName=this, Path=ReportLevel, Mode=TwoWay}" 

binds to a ReportLevel property in your UserControl. There is however no such property, because it is in the DataContext of the UserControl. The binding should look like shown below. Please also note that a two-way binding on the ItemsSource property doesn't make sense, as the control never sets that property.

ItemsSource="{Binding Path=ReportLevel}" 

That said, you do usually not have dependency properties in view models. Instad, the view model classes should implement the INotifyPropertyChanged interface.

You also have to actually fire the PropertyChanged event when the ReportLevel property changes:

private ObservableCollection<ReportLevel> reportLevel;
public ObservableCollection<ReportLevel> ReportLevel
{
    get { return reportLevel; }
    set
    {
        reportLevel = value;
        OnPropertyChanged("ReportLevel");
    }
}

Upvotes: 1

Related Questions