簡體   English   中英

WPF - CheckBox IsChecked by List 其中包含字符串

[英]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")
    };

    ...

在此處輸入圖像描述

class 音頻文件

這是一個 model class 存儲一些數據,也是從“評論”字段中提取的標簽

public class Audiofile {
    ...

    public List<Tag> LocationTags
    {
        get => _locationTags;
        set
        {
            SetProperty(ref _locationTags, value);
            HasChanges = true;
        }
    }
}

標簽 class

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.

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