简体   繁体   中英

Forcing a ListBox to re-render

Background :

I have a ListBox containing items defined by DataTemplates. Right now, if an object in the list has the property IsEditable set to true, the item's property information will be displayed inside of textboxes (via DataTemplate change), instead of textblocks (so the user can edit the content of that list item)

IsEditable is toggled on/off by a button inside of each list item. I have been told that we need to keep the state of all objects consistent, which means I can't just rebind the ItemsSource and lose everything.

Currently, I'm using this to re-render:

this.lbPoints.Dispatcher.Invoke(DispatcherPriority.Render, new Action(() => { }));

Question:

The aforementioned code snippet KIND OF does its job. By "kind of", I mean, it does eventually cause my data to become re-rendered, but only when I scroll to the bottom of the list and then scroll back up to the item i'm trying to re-render.

1) How can I re-render the data immediately without having to scroll around to get it to show up?

The guys commenting are right that you're going about this the wrong way... there is rarely a need to force a ListBox to re-render . You're probably causing yourself some additional grief trying to switch the DataTemplate s (although it is possible). Instead of that, think about data binding the TextBox.IsReadOnly property to your IsEditable property:

<TextBox IsReadOnly="{Binding IsEditable}" Text="{Binding Text}" />

Another alternative is to use a BooleanToVisibilityConverter to show a different Grid in your DataTemplate when your IsEditable property is true . Unfortunately, that Converter doesn't have an inverse operation, so you could create an IsNotEditing property to bind to the Grid in the DataTemplate that is originally displayed. I'm not sure if that's clear... see this example:

<DataTemplate DataType="{x:Type YourPrefix:YourDataType}">
    <Grid>
        <Grid Visibility="{Binding IsNotEditing, Converter={StaticResource 
            BooleanToVisibilityConverter}}">
            <!-- Define your uneditable UI here -->
        </Grid>
        <Grid Visibility="{Binding IsEditing, Converter={StaticResource 
            BooleanToVisibilityConverter}}">
            <!-- Define your editable UI here -->
        </Grid>
    </Grid>
</DataTemplate>

You could also define your own BooleanToVisibilityConverter class that has an IsInverted property, so that you can just use the one IsEditing property. You'd need to declare two Converters still, like this:

<Converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<Converters:BoolToVisibilityConverter x:Key="InvertedBoolToVisibilityConverter" 
    IsInverted="True" />

Then your XAML would be like this:

<Grid Visibility="{Binding IsEditing, Converter={StaticResource 
    InvertedBoolToVisibilityConverter}}">
    <!-- Define your uneditable UI here -->
</Grid>
<Grid Visibility="{Binding IsEditing, Converter={StaticResource 
    BoolToVisibilityConverter}}">
    <!-- Define your editable UI here -->
</Grid>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM