0

I have a DataGrid that displays its rows and columns through data binding. My question is, how do I clean up the display of my DataGrid? For example, getting rid of unused space by setting the column width. Usually I would set the width for every DataGridTextColumn, but this time I don't even need to use that line in the XAML(and it also doesn't work because I'm populating using data binding).

My DataGrid in use (See all the excess space on the right?):

enter image description here

XAML of the DataGrid:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding TransInfoCollection}" IsReadOnly="True" SelectedItem="{Binding SelectedTransponder}" Margin="12,12,14,60" CanUserResizeColumns="False" CanUserResizeRows="True" >
        <DataGrid.Columns>
            <DataGridTextColumn Header="{DynamicResource transLocation}" Binding="{Binding Path=Location}" Width="90" />
            <DataGridTextColumn Header="{DynamicResource transponder}" Binding="{Binding Path=Tranponder}" Width="*" />
        </DataGrid.Columns>
    </DataGrid>

ViewModel of the window:

public class TransponderMaintenanceViewModel : PropertyChangedBase
{
    private ObservableCollection<TransponderProps> _transInfoCollection; //DataGrid Collection
    private TransponderProps _selectedTransponder;

    private Command _deleteCommand;

    HierarchicalVM pathLocationsNode = App.MainTree.Data[2].Children[0]; //Path -> Locations

    public TransponderMaintenanceViewModel()
    {
        TransInfoCollection = new ObservableCollection<TransponderProps>();

        _deleteCommand = new Command(DeleteCommand_Ops);

        for (int i = 0; i < pathLocationsNode.Children.Count(); i++) //Adds Transponder information to DataGrid
        {
            if (pathLocationsNode.Children[i].Children[0].Children.Count() > 0)
            {
                for (int j = 0; j < pathLocationsNode.Children[i].Children[0].Children.Count(); j++)
                {
                    TransInfoCollection.Add(new TransponderProps { Location = new MultiItemString(new[] { Regex.Match(pathLocationsNode.Children[i].DisplayName.Value, @"\d+").Value }, false), 
                        Transponder = new MultiItemString(new[] { pathLocationsNode.Children[i].Children[0].Children[j].DisplayName.Value }, false) });
                }
            }
        }
    }

    //Prop for Collection that will store Transponders and their Location
    public ObservableCollection<TransponderProps> TransInfoCollection
    {
        get { return _transInfoCollection; }
        set
        {
            _transInfoCollection = value;
            NotifyPropertyChange(() => TransInfoCollection);
        }
    }

    //Prop for the SelectedItem in the DataGrid
    public TransponderProps SelectedTransponder
    {
        get { return _selectedTransponder; }
        set
        {
            _selectedTransponder = value;
            NotifyPropertyChange(() => SelectedTransponder);
        }
    }

    //Delete Command
    public Command DeleteCommand { get { return _deleteCommand; } }
    private void DeleteCommand_Ops()
    {
        for (int i = 0; i < pathLocationsNode.Children.Count(); i++) //Delete Transponder from CartTools
        {
            for (int j = 0; j < pathLocationsNode.Children[i].Children[0].Children.Count(); j++)
            {
                if (pathLocationsNode.Children[i].Children[0].Children[j].DisplayName.Value == SelectedTransponder.Transponder.Value)
                {
                    var transParent = pathLocationsNode.Children[i].Children[0];
                    transParent.Children.Remove(transParent.Children[j]);
                }
            }
        }

        TransInfoCollection.Remove(SelectedTransponder); //Remove Transponder from DataGrid
    }
}

public class TransponderProps : PropertyChangedBase
{
    private MultiItemString _location, _transponder;

    public TransponderProps()
    {

    }

    public MultiItemString Location
    {
        get { return _location; }
        set
        {
            _location = value;
            NotifyPropertyChange(() => Location);
        }
    }
    public MultiItemString Transponder
    {
        get { return _transponder; }
        set
        {
            _transponder = value;
            NotifyPropertyChange(() => Transponder);
        }
    }
}
Eric after dark
  • 1,768
  • 4
  • 31
  • 79

1 Answers1

0

If you don't autogenerate the columns you can control many of the properties of each column. If you use width = "*" it is a wild card and will take up the rest of the space.

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding TransInfoCollection}" IsReadOnly="True" SelectedItem="{Binding SelectedTransponder}" Margin="12,12,14,60" CanUserResizeColumns="False" CanUserResizeRows="True"  >
    <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Path=Location}" Header="Location" Width="90" />
                <DataGridTextColumn Binding="{Binding Path=Transponder}" Header="Transponder" Width="*" />                           
     </DataGrid.Columns>       
</DataGrid>
Felix Castor
  • 1,598
  • 1
  • 18
  • 39
  • Thanks for your answer @FelixCastor! This looks like something that would work, however I am getting an `InvalidOperationException`(Items Collection must be empty before using `ItemsSource`) because creating those `DataGridTextColumns` apparently adds to the `ItemsSource` of the `DataGrid` or something. Is there any way around this? – Eric after dark Oct 29 '14 at 16:15
  • So, I'm not sure why that would throw an error. What type of data structure is the collection you are trying to display? The above example can be used in the context where you have `List list` and `Location` and `Transponder` are properties of SomeObject. So you are binding the `DataGrid` to the list and the columns to the properties of the objects contained in the list. – Felix Castor Oct 29 '14 at 16:43
  • Also, did you set `AutoGenerateColumns="False"` that's important? – Felix Castor Oct 29 '14 at 16:47
  • I did set `AutoGenerateColumn="False"`. As far as I know I am doing exactly what you said in your first comment. I am binding the `DataGrid` to an `ObservableCollection` and the columns to the properties contained in the collection. I will post what I have in my ViewModel in the question for you. – Eric after dark Oct 29 '14 at 17:03
  • Cool. After checking out your link the exception is taken care of. I have still posted my code. Thanks for your help. – Eric after dark Oct 29 '14 at 17:10