Элемент управления EmptyListBox не получает уведомления об изменении ItemsSouce (silverlight / wp7) - PullRequest
0 голосов
/ 04 апреля 2011

Попытка может разрешить отображение «нет данных», если в списке нет элементов.Поскольку я нахожусь на wp7 и использую silverlight, я не могу использовать DataTriggers, поэтому я создал элемент управления, чтобы он работал одинаково во всем приложении.НО, если вы установите точку останова для метода set - он вообще не вызывается!

Контрольный класс

public class EmptyListBox : ListBox
{
    public new IEnumerable ItemsSource
    {
        get 
        {
            return base.ItemsSource; 
        }

        set
        {    
            // never here
            base.ItemsSource = value;
            ItemsSourceChanged();
        }
    }

    protected virtual void ItemsSourceChanged()
    {
        bool noItems = Items.Count == 0;

        if (noItems)
        {
            if (Parent is System.Windows.Controls.Panel)
            {
                var p = Parent as Panel;

                TextBlock noData = new TextBlock();
                noData.Text = "No data";
                noData.HorizontalAlignment = HorizontalAlignment;
                noData.Width = Width;
                noData.Height = Height;
                noData.Margin = Margin;

                p.Children.Add(noData);
                Visibility = System.Windows.Visibility.Collapsed;
            }
        }
    }
}

Это xaml

<my:EmptyListBox ItemsSource="{Binding Path=MyData}" Name="myListBox">
    <my:EmptyListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=name}" />
        </DataTemplate>
    </my:EmptyListBox.ItemTemplate>
</my:EmptyListBox>

Кодовое обозначение:

    ClientModel ClientInfo { get; set; }

    public ClientView()
    {
        ClientInfo = new ClientModel();
        ClientInfo.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(DataReady);

        DataContext = ClientInfo
    }

ClientModel класс:

public class ClientModel : INotifyPropertyChanged
{
    MyData _myData;
    public MyData MyData 
    {
        get
        {
            return _myData;
        }

        set
        {
            _myData = value;
            NotifyPropertyChanged("MyData");
        }
    }

    public void GetClient(int id)
    {
        // fetch the network for data
    }
}   

ССЫЛКА НА РЕШЕНИЕ. ZIP, КОТОРЫЙ ПОКАЗЫВАЕТ ПРОБЛЕМУ

http://rapidshare.com/files/455900509/WindowsPhoneDataBoundApplication1.zip

Ответы [ 5 ]

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

Я думаю, что решение, которое я бы выбрал, выглядит примерно так:

  1. Определение новой группы визуальных состояний ItemsStates и двух визуальных состояний: NoItems и HasItems .
    1. В ControlTemplate для своего пользовательского списка добавьте визуальное дерево для вашего состояния «без данных».
    2. В состоянии NoItems установите Visibility вашегоДля элементов "no data" установлено значение Visible и для Visibility значения по умолчанию ItemsPresenter установлено значение Collapsed.
    3. В состоянии HasItems поменяйте местами Visibility этихelements.
    4. В переключателе переопределения OnApplyTemplate в состояние Empty по умолчанию: VisualStateManager.GoToState(this, "Empty", true);
    5. В переопределении OnItemsChanged проверьте, является ли источник элементовпусто и используйте VisualStateManager для переключения между этими состояниями соответственно.

Это должно работать:)

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

Ваш новый ItemSource должен быть DependencyProperty.Все, что работает с Bindings, должно быть DependencyProperty.Просто сделайте это DependencyProperty.

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

попробуйте реализовать интерфейс INotifyPropertyChanged и использовать для ItemsSource ObservableCollection.В установщике вашего свойства просто вызовите метод OnPropertyChanged.

Возможно, это поможет.

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

Попробуйте добавить Mode = TwoWay к привязке ItemsSource:

<my:EmptyListBox ItemsSource="{Binding Path=MyData, Mode=TwoWay}" Name="myListBox">
    <my:EmptyListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=name}" />
        </DataTemplate>
    </my:EmptyListBox.ItemTemplate>
</my:EmptyListBox>
0 голосов
/ 04 апреля 2011

Создать ItemsSource как DependencyProperty.

Пример:

 public IEnumerable ItemsSource
 {
   get { return (IEnumerable)base.GetValue(ItemsSourceProperty); }
   set { base.SetValue(ItemsSourceProperty, value); }
 }

 public static DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register(
            "ItemsSource",
            typeof(IEnumerable),
            typeof(EmptyListBox),
            new PropertyMetadata(null));
...