0
votes

I need to display to the user two listboxes - one on either side of the window - and allow the user to choose how much screen space is devoted to each. I have achieved that much with the following code:

<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{Binding FirstColumnWidth}" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <ListBox Name="FirstColumn" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Grid.Column="0" />
    <GridSplitter Name="gridSplitter1" Width="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Grid.Column="1" />
    <ListBox Name="SecondColumn" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Grid.Column="2" />
</Grid>

However, whilst the binding will retrieve an initial width for the first column and size them both accordingly, using the GridSplitter to resize them simply replaces the binding with the new value. How can I retrieve the new value so that I can persist it?

Ideally, the solution needs to play nicely with MVVM - I'm using Caliburn and trying to keep the code as clean as possible (my view model contains the FirstColumnWidth property that is currently being bound).

1
Width only gets set at the beginning. ActualWidth is the property for actual width. You might be able bind ActualWidth as write only property (mode). But I recall a post where there was a problem with this even though it made perfect sense.paparazzo
You need to have a look at ActualWidth property. Check this for more information on how to access it from the view model: stackoverflow.com/questions/4438412/…Adrian Fâciu

1 Answers

0
votes

There are two solutions that I can think of.

1. Use the different binding modes available and the Width and ActualWidth properties.

Example

<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="{Binding Path=FirstColumnWidth, Mode=OneTime}" />
        <ColumnDefinition Width="3" />
        <ColumnDefinition Width="{Binding Path=SecondColumnWidth, Mode=OneTime}" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid Grid.Column="0" ActualWidth="{Binding Path=FirstColumnWidth, Mode=OneWayToSource}">
        <ListBox HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
    </Grid>
    <GridSplitter Grid.Column="1" Width="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
    <Grid Grid.Column="2" ActualWidth="{Binding Path=SecondColumnWidth, Mode=OneWayToSource}">
        <ListBox HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
    </Grid>
</Grid>

or 2. Override the current/default behaviour of the grid splitter using the attached behaviour pattern (tutorial on CodeProject). I will post of code sample for this tomorrow when I'm at my desk.