mercredi 8 mars 2017

WPF TreeView CheckBox Binding - How to populate ViewModel with checked boxes

I'm slightly confused about how to set up a CheckBox with a binding that ensures that my ViewModel is populated with all the checked fields. I have provided some of the code and a description at the bottom.

My Xaml file let's call it TreeView.xaml:

<TreeView x:Name="availableColumnsTreeView"          
          ItemsSource="{Binding Path=TreeFieldData, Mode=OneWay, Converter={StaticResource SortingConverter}, ConverterParameter='DisplayName.Text'}">

    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate x:Uid="HierarchicalDataTemplate_1" ItemsSource="{Binding Path=Children, Mode=OneWay, Converter={StaticResource SortingConverter}, ConverterParameter='DisplayName.Text'}">
            <CheckBox VerticalAlignment="Center" IsChecked="{Binding IsSelected, Mode=TwoWay}">
                <TextBlock x:Uid="TextBlock_1" Text="{Binding DisplayName.Text, Mode=OneWay}" />
            </CheckBox>              
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

The "code behind" TreeView.xaml.cs

public partial class MultipleColumnsSelectorView : UserControl
{
    public MultipleColumnsSelectorView()
    {
        InitializeComponent();
    }

    private MultipleColumnsSelectorVM Model
    {
        get { return DataContext as MultipleColumnsSelectorVM; }
    }
}

The ViewModel (tried to include only the relevant stuff) MultipleColumnsSelectorVM:

public partial class MultipleColumnsSelectorVM : ViewModel, IMultipleColumnsSelectorVM
{

    public List<TreeFieldData> SelectedFields
    {
        get { return GetValue(Properties.SelectedFields); }
        set { SetValue(Properties.SelectedFields, value); }
    }

    private void AddFields()
    {
       //Logic which loops over SelectedFields and when done calls a delegate which passes 
      //the result to another class. This works, implementation hidden
    }

The model TreeFieldData:

public class TreeFieldData : INotifyPropertyChanged
{    
    public event PropertyChangedEventHandler PropertyChanged;
    public IEnumerable<TreeFieldData> Children { get; private set; }
    private bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs("IsSelected"));
        }
    }
}

The Problem:

The behaviour that I want is when the user checks a checkbox, it should set the IsSelected property of TreeField (it does that right now) but then I want to go back to the ViewModel and make sure that this specific TreeField is added to SelectedFields. I don't really understand what the PropertyChangedEvent.Invoke does and who will receive that event? How can I make sure that SelectedFields gets populated so when AddFields() is invoked it has all the TreeField data instances which were checked?




Aucun commentaire:

Enregistrer un commentaire