Внутреннее свойство ItemsControl не обновляется при привязке к ItemsSource - PullRequest
1 голос
/ 21 апреля 2011

У меня есть ItemsControl, как показано ниже

<ItemsControl ItemsSource="{Binding MyClass.Links}"  >
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <Grid d:DesignWidth="450" d:DesignHeight="245" Height="Auto" Width="Auto">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" MinWidth="145"/>
                <ColumnDefinition Width="Auto" MinWidth="179"/>
            </Grid.ColumnDefinitions>
            <HyperlinkButton Content="{Binding ViewName}" IsEnabled="{Binding ViewEnabled, Mode=OneWay}" cmd:Click.Command="{Binding DataSource.ViewCommand, Source={StaticResource DataContextProxy}}" cmd:Click.CommandParameter="{Binding}" Margin="4"/>
        </Grid>
    </DataTemplate>
</ItemsControl.ItemTemplate>

У меня есть ObservableCollection следующего класса, к которому источник элементов привязывается

public class LinkClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public string ViewName { get; set; }
    private bool _viewEnabled;
    public bool ViewEnabled { 
    get { return this._viewEnabled; }
        set
        {
            if (value != this._viewEnabled)
            {
                this._viewEnabled = value;
                if (this.PropertyChanged != null)
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                          this.PropertyChanged(this, new PropertyChangedEventArgs("ViewEnabled"))
                        );
                }
            }
        }
    }
}

Когда команда нажата в модели представления, ViewEnabled связанной ссылки получает значение false (отключить ссылку для просмотра, на который я смотрю). Проблема в том, что ссылка на самом деле не отключается (IsEnabled имеет значение false).

Итак, последний вопрос: почему это не работает? Я новичок в MVVM и Silverlight, так что я надеюсь, что это что-то простое.

UPDATE

Я устанавливаю для свойства ViewEnabled значение true для всех, кроме связанного LinkClass нажатой кнопки, для которого я устанавливаю значение false. Он запускает событие PropertyChanged для каждого (который изменяется), но не обновляет пользовательский интерфейс. Я запустил пустой конвертер с привязкой, и при щелчке по ссылке он не срабатывает, поэтому PropertyChanged не пузырится должным образом (или, как я подозреваю, должен в любом случае).

Вот код, устанавливающий свойства ViewEnabled моей коллекции LinkClass:

public ICommand ViewCommand
    {
        get {
            return new DelegateCommand<object>(param =>
                {
                    this.ViewSelected((LinkClass)param);
                }); 
        }
    }

    public void ViewSelected(LinkClass link)
    {
                foreach (var containerLink in _myClass.Links)
                {
                    if (containerLink == link)
                        containerLink.ViewEnabled = false;
                    else
                        containerLink.ViewEnabled = true;
                }
        ...other code here
    }

Ответы [ 3 ]

1 голос
/ 22 апреля 2011

Ну, на самом деле это может быть отключено, но если ваш ViewCommand не обращает внимания на это свойство, то вы застряли.Тем более, что похоже, что эта команда является вложенным свойством.

Гугл получил меня этот пост , на который вы, возможно, захотите посмотреть.

Но лично я бы посмотрел на вашуCanExecute вашего ViewCommand и убедитесь, что он работает только если ViewEnabled == true

0 голосов
/ 24 апреля 2011

Следуя совету Хосе, я посмотрел на метод canExecute ViewCommand (DelegateCommand), который я использовал, но реализация метода не решила проблему, поскольку он был запущен только один раз, а не при изменении.Я нашел пример, рекомендующий использовать обработчик события PropertyChanged класса INotifyPropertyChanged для вызова метода RaiseCanExecuteChanged () DelegateCommand.Я сделал это для всех экземпляров LinkClass, как показано здесь для 1, прежде чем установить его на _myClass.Links:

var link = new LinkClass()
                             {
                                 ...
                                 ViewEnabled = true
                             };
                            link.PropertyChanged += new PropertyChangedEventHandler(link_PropertyChanged);
                            return link;

Я сделал это, но безрезультатно.Затем я нашел это сообщение в блоге: DelegateCommand в Prism теряет обработчик событий, и CanExecute никогда не вызывается Затем я переключился с Prism на класс RelayCommand, и это сработало!Надеюсь, это поможет кому-то еще.

ОБНОВЛЕНИЕ

Фактическая проблема заключалась в использовании Prism cmd: Click.Command и cmd: Click.CommandParameter в xaml.Переключение с этих свойств на Command и CommandParameter в xaml, как я делал после переключения на RelayCommand, - вот что фактически заставило его работать,

0 голосов
/ 21 апреля 2011

Когда я использовал MVVM, в установщике моих свойств у меня был метод с именем NotifyPropertyChanged (), и он вызывал его, передавая строковое значение для имени свойства. Я не уверен, что делает Deployment.Current.Dispatcher.BeginInvoke (...), но этот метод всегда работал для меня.

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;

        if (handler.IsNotNull())
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Так что в моей собственности я бы сделал что-то вроде ...

    public Nullable<int> UpdatedBy
    {
        get { return _updatedBy; }
        set
        {
            if (_updatedBy.IsEqualTo(value))
                return;

            _updatedBy = value;
            NotifyPropertyChanged("UpdatedBy");
        }
    }

Кроме того, просто хватайтесь за соломинку, но попробуйте поставить {Binding Path = ViewEnabled, ...} Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...