Can somone give example of Dependency Property in

2019-02-26 16:28发布

问题:

Can somone give example of Dependency Property in ViewModel in WPF passed as datacontext to view. Will this require inheriting from DependencyObject? Lets say I want ListBox SelectedItem bound to a Dependency Property CurrentItem in ViewModel. I have it working from window object but same thing donnt work with ViewModel . In ViewModel I use GetProperty and SetProperty and not CLR property.

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>

回答1:

Although you can implement a ViewModel as a DependencyObject with dependency properties, most people agree that it's better to use a POCO object implementing INotifyPropertyChanged... Have a look at this article by Kent Boogaart for a detailed comparison between the two approaches. There's also a SO question about this



回答2:

In order to define a DependencyProperty in your view model, your view model class must derive from DependencyObject. Otherwise the DependencyProperty won't work right.

Do you really need the property to be a DependencyPropety? Have you looked into implementing INotifyPropertyChanged instead?