依赖属性不绑定到视图

时间:2015-03-06 11:28:33

标签: c# wpf xaml dependency-properties

我试着做的是根据所选择的树视图项填充组合框。根据选择的节点,将使用不同的报告级别列表填充组合框。

组合框在用户控件中,我试图绑定到我在MainViewModel中的依赖属性ReportLevel。如果我将组合框的值设置为罚款但我希望能够在用户选择树上的不同节点时更新它。

这是我的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}"/>

我的代码

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

       DataContext = new MainViewModel();

在我的MainViewModel中我有这个

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

并有一个设置此值的方法

            ReportLevel = c.GetUserReportLevel();

我用组合框的ItemSource尝试过各种各样的东西,但没有成功。

对此事的任何帮助都表示赞赏

谢谢, 马蒂 编辑:已更新我的代码,但仍然没有运气这件事,任何想法? 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}"/>

并在MainViewModel中

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

我的MainViewModel继承了一个更改了INotifyProperty的基类和一个实现

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

1 个答案:

答案 0 :(得分:1)

绑定

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

绑定到UserControl中的ReportLevel属性。但是没有这样的属性,因为它位于UserControl的DataContext中。绑定应如下所示。还请注意,ItemsSource属性上的双向绑定没有意义,因为控件永远不会设置该属性。

ItemsSource="{Binding Path=ReportLevel}" 

也就是说,在视图模型中通常没有依赖属性。在Instad中,视图模型类应该实现INotifyPropertyChanged接口。

ReportLevel属性发生更改时,您还必须实际触发PropertyChanged事件:

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