簡體   English   中英

綁定ObservableCollection <class> ListBox DataTemplate的字段

[英]Binding ObservableCollection<class> fields to ListBox DataTemplate

我是一名剛剛完成暑期實習的學生,在學校開學之前,我帶回了一個正在進行的項目。 這個項目中有一個秒表,我寧願使用綁定到ListBox的ObservableCollection作為我的拆分時間,而不是使用listbox.Items.Add()。 當我添加到ObservableCollection時,ListBox UI不會更新。 任何人都可以針對我錯過的內容或做錯的事情為我指明正確的方向嗎?

我有TimeSplits課程:

public class TimeSplits : INotifyPropertyChanged
{

    private int _hours;
    private int _minutes;
    private int _seconds;

    public int hours
    {
        get
        {
            return _hours;
        }
        set
        {
            _hours = value;
            NotifyPropertyChanged(hours);
        }
    }
    public int minutes
    {
        get
        {
            return _minutes;
        }
        set
        {
            _minutes = value;
            NotifyPropertyChanged(minutes);
        }
    }
    public int seconds
    {
        get
        {
            return _seconds;
        }
        set
        {
            _seconds = value;
            NotifyPropertyChanged(seconds);
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(int propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(nameof(propertyName)));
        }
    }

    public override string ToString()
    {
        return hours.ToString() + ":" + minutes.ToString() + ":" + seconds.ToString();
    }
}

和我的Page中的ObservableCollection:

public partial class StopwatchPage : Page , INotifyPropertyChanged
{
...
    public ObservableCollection<TimeSplits> splits = new ObservableCollection<TimeSplits>();
...
    public StopwatchPage()
    {
        DataContext = this;
        InitializeComponent();
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Tick += new EventHandler(stopwatchTimer);
    }
...
    private void splitButton_Click(object sender, RoutedEventArgs e)
    {
        TimeSplits split = new TimeSplits();
        split.hours = Hours;
        split.minutes = Minutes;
        split.seconds = Seconds;
        splits.Add(split);
    }
...
}

和我的xaml:

<ListBox x:Name="newSplitListBox" HorizontalAlignment="Left" Margin="139,0,0,47" Width="185" Height="268" VerticalAlignment="Bottom" ItemsSource="{Binding splits}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding hours}"/>
                    <TextBlock Text="{Binding minutes}"/>
                    <TextBlock Text="{Binding seconds}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

我敢肯定,這是我所不知道的小事情,因為我今年夏天才開始學習數據綁定。 任何幫助是極大的贊賞! 提前致謝。

看來您在錯誤的位置輸入了nameof() 當前代碼的讀取方式將始終發送“ propertyName”的值作為已更改屬性的名稱,而不管實際更改了哪個屬性。

嘗試這個:

public int hours
{
    get
    {
        return _hours;
    }
    set
    {
        _hours = value;
        NotifyPropertyChanged();
    }
}

然后,在您的NotifyPropertyChanged() ,執行以下操作:

private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName);
    }
}

編輯:添加了以下修復程序:

另外,ObservableCollection必須是一個屬性。 更改此代碼:

public ObservableCollection<TimeSplits> splits = new ObservableCollection<TimeSplits>();

對此:

public ObservableCollection<TimeSplits> Splits { get; set; } = new ObservableCollection<TimeSplits>();

我從Xamarin的ViewModel模板中學到了一個技巧,極大地幫助了我。 這是它生成的用於處理可觀察視圖模型(類似於ObservableCollection)的代碼。

    protected bool SetProperty<T>(ref T backingStore, T value,
        Action onChanged = null,
        [CallerMemberName]string propertyName = "")
    {
        if (EqualityComparer<T>.Default.Equals(backingStore, value))
            return false;

        backingStore = value;
        onChanged?.Invoke();
        OnPropertyChanged(propertyName);
        return true;
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        var changed = PropertyChanged;
        if (changed == null)
            return;

        changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion

然后,要使用此功能,只需將其添加到您的屬性中:

private string _title = string.Empty;
public string Title
{
    get => _title;
    set => SetProperty(ref _title, value);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM