当用户选择某些数据时,我正在尝试更新 ListBox 中的值。出于某种原因, ListBox 不会实时更新,我必须关闭应用程序并重新打开才能显示数据。
我已经将模式更改为MVVM,因为人们已经说过这样更容易使用。
在我的表单上,我设置了DataContext:
public Live()
{
LiveMainViewModel graphUpdater = new LiveMainViewModel();
this.DataContext = graphUpdater;
}
在我的ViewModel构造函数中,我调用了一个刷新:
public LiveMainViewModel()
{
RefreshListBox();
}
我在附加OnPropertyChanged事件时设置了一个Property:
public ObservableCollection<ITimeLineDataItem> SlideDataItems {
get { return _slideDataItems; }
set
{
_slideDataItems = value;
OnPropertyChanged("SlideDataItems");
}
}
private ObservableCollection<ITimeLineDataItem> _slideDataItems;
在我的刷新方法中,我将新项目添加到列表中:
public void RefreshListbox()
{
_slideDataItems = new ObservableCollection<ITimeLineDataItem>();
foreach (podiaPublish.Marker pMarker in Global.gChapter.MarkerList)
{
if (pContent.Markup.Contains(".png"))
{
var brush = new ImageBrush(bitmapSource);
var lb1 = new TempDataType()
{
Name = pContent.Markup,
BackgroundImage = brush
};
_slideDataItems.Add(lb1);
}
}
}
因此,当我实时添加项目时, ListBox 不会随数据一起更新,但是当我重新加载应用程序时,数据将会出现。
如何使用用户添加的数据更新 ListBox ?
输出窗口:
System.Windows.Data Warning: 56 : Created BindingExpression (hash=10555762) for Binding (hash=14988671)
System.Windows.Data Warning: 58 : Path: 'SlideDataItems'
System.Windows.Data Warning: 60 : BindingExpression (hash=10555762): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=10555762): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=10555762): Attach to System.Windows.Controls.ListBox.ItemsSource (hash=30133081)
System.Windows.Data Warning: 67 : BindingExpression (hash=10555762): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=10555762): Found data context element: ListBox (hash=30133081) (OK)
System.Windows.Data Warning: 71 : BindingExpression (hash=10555762): DataContext is null
System.Windows.Data Warning: 65 : BindingExpression (hash=10555762): Resolve source deferred
我如何绑定:
<ListBox x:Name="ListSrc" Background="#ececec" ItemsSource="{Binding SlideDataItems}" dd:DragDrop.IsDragSource="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" BorderBrush="Transparent" BorderThickness="0">
我的自定义类:
public interface ITimeLineDataItem
{
TimeSpan? StartTime { get; set; }
TimeSpan? EndTime { get; set; }
Boolean TimelineViewExpanded { get; set; }
}
答案 0 :(得分:0)
这是因为您将绑定对象更改为另一个但不通知您的绑定。在这种情况下,您可以用下一个代码替换您的代码:
public void RefreshListbox()
{
var slideDataItems = new ObservableCollection<ITimeLineDataItem>();
foreach (podiaPublish.Marker pMarker in Global.gChapter.MarkerList)
{
if (pContent.Markup.Contains(".png"))
{
var brush = new ImageBrush(bitmapSource);
var lb1 = new TempDataType()
{
Name = pContent.Markup,
BackgroundImage = brush
};
slideDataItems.Add(lb1);
}
}
SlideDataItems = slideDataItems;
}
在这种情况下,您可以使用属性的通知更改对象。将触发数据目标(ListBox)并更新其针对新数据源的表示。
另一种方法是通过切换来改变现有的数据源
_slideDataItems = new ObservableCollection<ITimeLineDataItem>();
到
_slideDataItems.Clear();
并在其声明中初始化字段:
private ObservableCollection<ITimeLineDataItem> _slideDataItems = new ObservableCollection<ITimeLineDataItem>();
现在您将始终拥有一个数据源对象,并可以通过添加新元素,删除元素或清除所有集合来更新它。
答案 1 :(得分:0)
尝试使用xhtml:
ItemsSource="{Binding SlideDataItems, UpdateSourceTrigger=PropertyChanged}"
也许还可以添加Mode = TwoWay
编辑:
为什么要刷新ListBox并创建一个新的ObservableCollection?
尝试在最后触发方法OnPropertyChanged("SlideDataItems");
中的RefreshListbox()
。
答案 2 :(得分:0)
我认为你已经错误地实现了ObservableCollection。 ITimeLineDataItem的属性应该实现INotifyPropertyChanged而不是集合。
public class MyCollection : ObservableCollection<ITimeLineDataItem>
{
}
public class ITimeLineDataItem: INotifyPropertyChanged
{
private string _aProperty;
public string AProperty
{
get { return _aProperty; }
set
{
if (_aProperty!= value)
{
_aProperty= value;
OnPropertyChanged("AProperty");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
然后在您的视图模型(也将是您的数据上下文)中,您将拥有:
MyCollection<ITimeLineDataItem> SlideDataItems {get; set;}
和
SlideDataItems = MyCollection<ITimeLineDataItem>();
最后,您需要在xaml
ItemsSource="{Binding SlideDataItems}"
答案 3 :(得分:0)
一次创建一个ObservableCollection,然后只需在Refresh方法中将其清除即可。
public ObservableCollection<ITimeLineDataItem> SlideDataItems {
get { return _slideDataItems; }
set
{
_slideDataItems = value;
OnPropertyChanged("SlideDataItems");
}
}
private ObservableCollection<ITimeLineDataItem> _slideDataItems = new ObservableCollection<ITimeLineDataItem>();
在Refresh方法中,清除ObservableCollection,但不要重新创建它。
public void RefreshListbox()
{
SlideDataItems.Clear();
foreach (podiaPublish.Marker pMarker in Global.gChapter.MarkerList)
{
if (pContent.Markup.Contains(".png"))
{
var brush = new ImageBrush(bitmapSource);
var lb1 = new TempDataType()
{
Name = pContent.Markup,
BackgroundImage = brush
};
_slideDataItems.Add(lb1);
}
}
}