![](/img/trans.png)
[英]In WPF, how do I two-way bind a Checkbox's IsChecked to property to List<>.Contains?
[英]WPF - CheckBox IsChecked by List where it contains string
我正在生成一個 ItemsControl,其中包含由 List 生成的 CheckBoxes 列表。
我正在閱讀 mp3 文件的 Id3 標簽,尤其是“評論”字段。 然后我用正則表達式搜索兩個括號“[(.*?)]”之間的所有子字符串。 這些是文件包含的標簽。
在啟動時,我正在將配置文件讀入“AppSettings”,其中包含用作可用標簽的標簽列表。 此列表用於為 UI 生成 CheckBoxes。
public class AppSettings
{
...
public List<Tag> LocationTags { get; set; } = new List<Tag>()
{
new Tag("Club", "CLUB"),
new Tag("Bar", "BAR"),
new Tag("Radio", "RADIO")
};
...
這是一個 model class 存儲一些數據,也是從“評論”字段中提取的標簽
public class Audiofile {
...
public List<Tag> LocationTags
{
get => _locationTags;
set
{
SetProperty(ref _locationTags, value);
HasChanges = true;
}
}
}
public class Tag
{
/// <summary>
/// A User friendly name
/// </summary>
public string Name { get; set; }
/// <summary>
/// The key which is tagged, e.g. charts which is then encoded into [charts]
/// </summary>
public string Key { get; set; }
}
如前所述,視圖顯示帶有復選框的預定義標簽。
<ItemsControl ItemsSource="{Binding AppSettings.LocationTags}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Margin="16,4,4,4"
IsChecked="{Binding ElementName=Root, Path=DataContext.SelectedAudiofile.LocationTags.ThisIsWhatIWantToBind}" />
<TextBlock Text="{Binding Name}"
Margin="0,4,4,4"
Style="{StaticResource TextBlockLight}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
基本上為視圖提供所需的數據。
public class xxViewModel{
...
public Audiofile SelectedAudiofile { get;set; }
}
如您所見,通過列表生成復選框不是問題,但是如果 Audiofile.LocationTags 包含具有相等鍵的標簽,我如何在它們上設置 IsChecked 屬性? 我還想在 CheckBox.IsChecked state 更改時向 Audiofile.LocationTags 列表添加一個新標簽
您所要做的就是為數據 model 添加相應的屬性。
由於 class Tag
用作綁定源,它應該實現INotifyPropertyChanged
。 每個不是DependencyObject
並因此無法實現DependencyProperty
的綁定源都應始終實現INotifyPropertyChanged
。
視圖 model 監聽 model 變化:
public class xxViewModel : INotifyPropertyChanged
{
public xxViewModel()
{
this.SelectedAudiofile = new Audiofile();
// Initialize each Tag item
var tag = new Tag() { IsEnabled = true };
tag.EnabledChanged += OnAudiofileTagChanged;
this.SelectedAudiofile.LocationTags.Add(tag);
this.SelectedAudiofile.TagEnabled += OnAudiofileTagChanged;
}
private void OnAudiofileTagChanged()
{
var tag = new Tag() { IsEnabled = true };
tag.EnabledChanged += OnAudiofileTagChanged;
this.SelectedAudiofile.LocationTags.Add(tag);
}
...
public Audiofile SelectedAudiofile { get;set; }
}
為了通知 UI 有關集合的更改, LocationTags
屬性應該是ObservableCollection<T>
:
public class Audiofile : INotifyPropertyChanged
{
public AudioFile()
{
this.LocationTags = new ObservableCollection<Tag>();
}
public ObservableCollection<Tag> LocationTags
{
get => _locationTags;
set
{
SetProperty(ref _locationTags, value);
HasChanges = true;
}
}
}
該標簽實現了一個TagEnabled
事件:
public class Tag : INotifyPropertyChanged
{
public event EventHandler TagEnabled;
private void OnTagIsEnabledChanged() => this.TagEnabled?.Invoke(this, EventArgs.Empty);
private bool isEnabled;
public bool IsEnabled
{
get => this.isEnabled;
set
{
this.isEnabled = value;
OnPropertyChanged();
OnTagIsEnabledChanged();
}
}
/// <summary>
/// A User friendly name
/// </summary>
public string Name { get; set; }
/// <summary>
/// The key which is tagged, e.g. charts which is then encoded into [charts]
/// </summary>
public string Key { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
物品綁定:
<ItemsControl ItemsSource="{Binding AppSettings.LocationTags}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type Tag}">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsEnabled}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.