ViewModel中的依赖属性的任何示例?

时间:2009-09-30 21:07:01

标签: wpf properties dependencies

有人可以在WPF中的ViewModel中提供Dependency Property的示例作为datacontext进行查看。这需要继承DependencyObject吗? 假设我希望ListBox SelectedItem绑定到ViewModel中的依赖项属性CurrentItem。我从窗口对象工作,但同样的事情不适用于ViewModel。在ViewModel中,我使用GetProperty和SetProperty而不是CLR属性。

public partial class Window1 : Window
{
    ObservableCollection<Person> persons;
    public ObservableCollection<Person> Persons
    {
        get
        {
            return persons;
        }
        set
        {
            persons = value;
        }
    }

    public static readonly DependencyProperty InfoTextProperty =
           DependencyProperty.Register(
           "InfoText",
           typeof(Person),
           typeof(Window1),
           new FrameworkPropertyMetadata(
               new PropertyChangedCallback(ChangeText)));

    public Window1()
    {
        InitializeComponent();
        this.DataContext = this;
        List<Person> people = new List<Person>();
        people.Add(new Person("Makeda Wilde"));
        people.Add(new Person(" Rosamaria Becnel"));
        people.Add(new Person("Jarrett Bernstein"));
        people.Add(new Person(" Leopoldo Palmer"));
        people.Add(new Person("Tyron Fisher"));
        people.Add(new Person(" Elba Kilpatrick"));
        people.Add(new Person("Ivory Lavender"));
        persons = new ObservableCollection<Person>(people);

        //persons.CollectionChanged += 
        //     new  System.Collections.Specialized.NotifyCollectionChangedEventHandler(
        //     persons_CollectionChanged);
    }

    void persons_CollectionChanged(object sender,  System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
    }

    public ListBoxItem InfoText
    {
        get
        {
            return (ListBoxItem)GetValue(InfoTextProperty);
        }
        set
        {
            SetValue(InfoTextProperty, value);
        }
    }


    private static void ChangeText(DependencyObject source, DependencyPropertyChangedEventArgs e)
    {
        Person newPerson = (Person)e.NewValue;
        newPerson.IsSelected = true;

        Person oldPerson = (Person)e.OldValue;
        if (oldPerson != null)
        {
            oldPerson.IsSelected = false;
        }
    }

    //  #region INotifyPropertyChanged Members
    //  event PropertyChangedEventHandler PropertyChanged;
    //   // Create the OnPropertyChanged method to raise the event
    //protected void OnPropertyChanged(string name)
    //{
    //    PropertyChangedEventHandler handler = PropertyChanged;
    //    if (handler != null)
    //    {
    //        handler(this, new PropertyChangedEventArgs(name));
    //    }
    //}


    //  #endregion
}

public class Person : INotifyPropertyChanged
{
    private bool isselected = false;
    public Person(string name)
    {
        this.Name = name;
        this.IsSelected = false;
    }

    public string Name { get; set; }
    public bool IsSelected
    {
        get
        {
            return isselected;
        }
        set
        {
            isselected = value;
            OnPropertyChanged("IsSelected");
        }
    }

    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    // Create the OnPropertyChanged method to raise the event

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
    #endregion
}

<Grid>
    <ListBox Height="500"  Width="500" ItemsSource="{Binding Persons}"  Margin="104,46,212,0"  VerticalAlignment="Top"  SelectedItem="{Binding InfoText}"  >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Margin="2,2,2,2"  x:Name="tb" TextWrapping="Wrap" Text="{Binding Path=Name}"  />
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding Path=IsSelected}" Value="true">
                        <Setter Property="Background"  TargetName="tb" Value="Red"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

2 个答案:

答案 0 :(得分:4)

虽然您可以将ViewModel实现为具有依赖项属性的DependencyObject,但大多数人都认为最好使用实现INotifyPropertyChanged的POCO对象...请查看this article Kent Boogaart对两种方法进行了详细比较。关于此

还有一个SO question

答案 1 :(得分:1)

要在视图模型中定义DependencyProperty,您的视图模型类必须派生自DependencyObject。否则DependencyProperty将无效。

你真的需要这个属性是DependencyPropety吗?您是否考虑过实施INotifyPropertyChanged