数据绑定到 ObservableCollection 的列表框不会更新 UI
Listbox with databinding to ObservableCollection won't update UI
问题已经在标题中说明了。请仔细查看 XAML 和代码,因为我是 C# 的业余爱好者(只有基础知识)并且对数据绑定几乎是全新的。所以这是我的 XAML:
<ListBox x:Name="BoardList" ItemsSource="{Binding notes, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<TextBox IsReadOnly="True" ScrollViewer.VerticalScrollBarVisibility="Visible" Text="{Binding Text}" TextWrapping="Wrap" Foreground="DarkBlue"></TextBox>
<AppBarButton Visibility="{Binding visibility}" Icon="Globe" Click="OpenInBrowser" x:Name="Link"></AppBarButton>
<AppBarButton Icon="Copy" Click="Copy"></AppBarButton>
<AppBarButton Icon="Delete" Click="Delete"></AppBarButton>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
然后我在 Mainpage.xaml.cs
文件中创建了一个 ObservableCollection
:
public sealed partial class MainPage : Page
{
ObservableCollection<BoardNote> notes = new ObservableCollection<BoardNote>();
public MainPage() //empty for post
{
this.InitializeComponent();
}}
class BoardNote
:
class BoardNote : NotificationObject
{
private string _text { get; set; }
public string Text
{
get { return _text; }
set
{
if (_text == value) return;
_text = value;
RaisePropertyChanged(() => Text);
}
}
public BoardNote(string text)
{
this._text = text ;
}
public Visibility visibility
{
get
{
if (_text.StartsWith("http"))
return Visibility.Visible;
else
return Visibility.Collapsed;
}
}
}
和 Notification
class:
class NotificationObject : INotifyPropertyChanged
{
protected void RaisePropertyChanged<T>(Expression<Func<T>> action)
{
var propertyName = GetPropertyName(action);
RaisePropertyChanged(propertyName);
}
private static string GetPropertyName<T>(Expression<Func<T>> action)
{
var expression = (MemberExpression)action.Body;
var propertyName = expression.Member.Name;
return propertyName;
}
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
如果我创建一个新的 Boardnote
例如在按钮上 Listbox
不会添加新项目。我不知道该怎么做,我是绑定和 INotifyPropertyChanged
class 的新手,但我很快就能理解新事物。
1.- DataContext 是一个 class 的实例,其中包含您需要的数据。
您可以像这样设置数据上下文:
<Page xmlns:local...>
<Page.DataContext>
<local:ViewModelClass/>
</Page.DataContext>
(你可以通过多种方式做到这一点,作为资源和许多其他东西)
2.- class ViewModelClass 应该包含一个名为 Notes 的 属性 并且必须是 属性.
public ObservableCollection<BoardNote> Notes {get;} = new ObservableCollection<BoardNote>();
3.- 如果需要更新数据,请不要重新实例化注释,只需清除它并重新添加项目即可。
4.- 实现 INotifyPropertyChanged 使 UI 使用新数据刷新视图很有趣。
更新:
如果将数据上下文设置为笔记实例:
<ListBox x:Name="BoardList" ItemsSource="{Binding}">
<ListBox.DataContext>
<local:Notes/>
</ListBox.DataContext/>
...
但是正如你所看到的,它有点困难,因为 Notes 应该是一个 class 所以你可以继承 ObservableCollection:
public class Notes : ObservableCollection<Note>
{
}
问题已经在标题中说明了。请仔细查看 XAML 和代码,因为我是 C# 的业余爱好者(只有基础知识)并且对数据绑定几乎是全新的。所以这是我的 XAML:
<ListBox x:Name="BoardList" ItemsSource="{Binding notes, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<TextBox IsReadOnly="True" ScrollViewer.VerticalScrollBarVisibility="Visible" Text="{Binding Text}" TextWrapping="Wrap" Foreground="DarkBlue"></TextBox>
<AppBarButton Visibility="{Binding visibility}" Icon="Globe" Click="OpenInBrowser" x:Name="Link"></AppBarButton>
<AppBarButton Icon="Copy" Click="Copy"></AppBarButton>
<AppBarButton Icon="Delete" Click="Delete"></AppBarButton>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
然后我在 Mainpage.xaml.cs
文件中创建了一个 ObservableCollection
:
public sealed partial class MainPage : Page
{
ObservableCollection<BoardNote> notes = new ObservableCollection<BoardNote>();
public MainPage() //empty for post
{
this.InitializeComponent();
}}
class BoardNote
:
class BoardNote : NotificationObject
{
private string _text { get; set; }
public string Text
{
get { return _text; }
set
{
if (_text == value) return;
_text = value;
RaisePropertyChanged(() => Text);
}
}
public BoardNote(string text)
{
this._text = text ;
}
public Visibility visibility
{
get
{
if (_text.StartsWith("http"))
return Visibility.Visible;
else
return Visibility.Collapsed;
}
}
}
和 Notification
class:
class NotificationObject : INotifyPropertyChanged
{
protected void RaisePropertyChanged<T>(Expression<Func<T>> action)
{
var propertyName = GetPropertyName(action);
RaisePropertyChanged(propertyName);
}
private static string GetPropertyName<T>(Expression<Func<T>> action)
{
var expression = (MemberExpression)action.Body;
var propertyName = expression.Member.Name;
return propertyName;
}
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
如果我创建一个新的 Boardnote
例如在按钮上 Listbox
不会添加新项目。我不知道该怎么做,我是绑定和 INotifyPropertyChanged
class 的新手,但我很快就能理解新事物。
1.- DataContext 是一个 class 的实例,其中包含您需要的数据。 您可以像这样设置数据上下文:
<Page xmlns:local...>
<Page.DataContext>
<local:ViewModelClass/>
</Page.DataContext>
(你可以通过多种方式做到这一点,作为资源和许多其他东西)
2.- class ViewModelClass 应该包含一个名为 Notes 的 属性 并且必须是 属性.
public ObservableCollection<BoardNote> Notes {get;} = new ObservableCollection<BoardNote>();
3.- 如果需要更新数据,请不要重新实例化注释,只需清除它并重新添加项目即可。
4.- 实现 INotifyPropertyChanged 使 UI 使用新数据刷新视图很有趣。
更新:
如果将数据上下文设置为笔记实例:
<ListBox x:Name="BoardList" ItemsSource="{Binding}">
<ListBox.DataContext>
<local:Notes/>
</ListBox.DataContext/>
...
但是正如你所看到的,它有点困难,因为 Notes 应该是一个 class 所以你可以继承 ObservableCollection:
public class Notes : ObservableCollection<Note>
{
}