WPF ListBox не обновляет значение связанных элементов при изменении элементов - PullRequest
0 голосов
/ 17 декабря 2018

В приложении есть Listbox, связанный с ObservableCollection, затем выбранный элемент привязывается к некоторым меткам: когда свойство метки элемента изменяется в метке, фактический объект (в данном случае Multimedia) обновляется (какЯ отладил), но затем список не обновляет отображаемое значение.

Класс Multimedia реализует INotifyPropertyChanged, но я не уверен, правильно ли я его использую.

Все остальное работает безлюбая проблема (кнопка добавления добавляет новый элемент в список, и он отображается так, как должен).

Я просматривал разные форумы, а также стек, и пробовал разные варианты, но при обновлении свойство все равно оставалось,это не обновляется в ListBox.

Это XMAL:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="135" />
        <RowDefinition Height="*" />
        <RowDefinition Height="45" />
    </Grid.RowDefinitions>
    <ListBox Name="mediaListBox"  ItemsSource="{Binding Path=MyData}" Grid.Row="0"/>
    <Grid Grid.Row="1"  DataContext="{Binding ElementName=mediaListBox, Path=SelectedItem}">

        ...

        <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=Title}" />
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Artist}" />
        <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=Genre}" />
        <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding Path=Type}" />
    </Grid>
    <Button Name="cmdAddMedia" Grid.Row="1" Click="cmdAddMedia_Click" Height="45" Margin="0,0,0,2" Grid.RowSpan="2" VerticalAlignment="Bottom">Add Item</Button>
</Grid>

Тогда здесь есть код C # главного окна:

public partial class MainWindow : Window
{
    public MultiMediaList MyData { get; set; }
    public void AddStuff()
    {
        MyData.Add(new Multimedia() { Title = "My Way", Artist = "Calvin Harris", Genre = "Pop", Type = Multimedia.MediaType.CD });
        MyData.Add(new Multimedia() { Title = "Inglorious Bastards", Artist = "Quentin Tarantino", Genre = "Violence", Type = Multimedia.MediaType.DVD });
    }
    public MainWindow()
    {
        MyData = new MultiMediaList();
        AddStuff();
        InitializeComponent();
        DataContext = this;            
    }
...
}

Инаконец, класс Multimedia и класс MultiMediaList:

public class Multimedia : INotifyPropertyChanged
{
    public enum MediaType { CD, DVD };

    private string _title;
    private string _artist;
    private string _genre;
    private MediaType _type;

    public string Title
    {
        get { return _title; }
        set
        {
            _title = value;
            NotifyPropertyChanged("Title");
        }
    }
    ...
    public override string ToString()
    {
        return _title + " - " + _artist + " [" + _genre + "] - " + getTypeString();
    }

    private string getTypeString()
    {
       if(Type == MediaType.CD) { return "CD"; }
        else { return "DVD"; }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
             PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

MultimediaList - это просто пустой класс, унаследованный от ObservableCollection

public class MultiMediaList: ObservableCollection<Multimedia>
{

}

Если вам нужно, я также могу загрузить полный код

Надеюсь, вы поможете мне и скажите мне, что я делаю неправильно.

1 Ответ

0 голосов
/ 17 декабря 2018

Очевидно, вы ожидаете, что ListBox автоматически вызывает метод ToString() объекта Мультимедиа всякий раз, когда изменяется его свойства.Это не так.

Вместо того, чтобы полагаться на ToString, объявите правильный ItemTemplate для ListBox:

<ListBox Name="mediaListBox" ItemsSource="{Binding MyData}" Grid.Row="0">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock>
                <Run Text="{Binding Title}"/>
                <Run Text="-"/>
                <Run Text="{Binding Artist}"/>
                <Run Text="["/><Run Text="{Binding Genre}"/><Run Text="]"/>
                <Run Text="{Binding Type}"/>
            </TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

TextBlock может быть записан короче:

<TextBlock>
    <Run Text="{Binding Title}"/> - <Run Text="{Binding Artist}"/> [<Run Text="{Binding Genre}"/>] <Run Text="{Binding Type}"/>
</TextBlock>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...