Search code examples
c#wpfbindingvisibilitydatagridcolumn

DataGridColumn binding only if object property is true


I'm currently facing a problem while trying to do some conditional binding in WPF. I've read up on the problem and it seems like "visibility" isn't really an option for DataGridColumns as it's not in the logicaltreeview. I currently have an object "Device" which contains a list of objects "Channel". These channels can be either input or output which is represented as a bool "isInput". What I'm trying to accomplish is to create two data grids, one with inputs and one with outputs.

<DataGrid Grid.Row="0" AutoGenerateColumns="False" ItemsSource="{Binding Path=Channels}">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=Type}" 
             Visibility="{Binding Path=(model:Channel.IsInput), 
             Converter={StaticResource BooltoVisibilityConverter}}"/>
        </DataGrid.Columns>
</DataGrid>

This is what I currently have but as the visibility doesn't seem to work I would like a way to either hide the whole row when IsInput=false or to skip it entirely.


Solution

  • If you want multiple grids, then you need multiple item collection filtered as required.

    For what you require, assuming that the total number of channel objects is relatively small, I'd do something like this.

    public class ViewModel: ViewModelBase
    {
        public ViewModel()
        {
            AllChannels = new ObservableCollection<Channel>();
            AllChannels.CollectionChanged += (s,e) =>
               { 
                   RaisePropertyChanged(nameof(InputChannels));
                   RaisePropertyChanged(nameof(OutputChannels));
               }
        }
    
        private ObservableCollection<Channel> AllChanels { get; }
    
        public IEnumerable<Channel> InputChannels => AllChannels.Where(c => c.IsInput);
        public IEnumerable<Channel> OutputChannels => AllChannels.Where(c => !c.IsInput);
    
        public void AddChannel(Channel channel)
        {
            AllChannels.Add(channel);
        }
    }        
    

    You can now create two grid controls and bind their ItemsSource property to InputChannels and OutputChannels.