Search code examples
uwpwinrt-xamlc++-winrt

TwoWay Binding doesn't update the IObservableVector


Hello fellow programmers,

i'm currently stuck because i can't figure out how these TwoWay bindings works. I have a SETTING class with an IObservableVector with IInspectables and a Page class with an IObservableVector with IInspectables, too. In the SETTING class the vector stores boxed winrt::hstring and the vector of the Page class stores SETTING classes.

I've tried to bind the hstrings to listviewitems and the listview to Pivotitems but the vector of the SETTING class wont get updated. But when I bind one item of the vector to a textbox it works perfectly fine and updates the first textbox in the listview too.

<Pivot HorizontalContentAlignment="Left" Margin="10" ItemsSource="{x:Bind settings, Mode=OneWay}">
    <Pivot.ItemTemplate>
        <DataTemplate x:DataType="local:SETTING">
            <StackPanel>
                <ListView ItemsSource="{x:Bind setting_values, Mode=OneWay}">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                             <StackPanel>
                                 <TextBox Text="{Binding Mode=TwoWay}" HorizontalAlignment="Stretch"></TextBox>
                              </StackPanel>
                         </DataTemplate>
                     </ListView.ItemTemplate>
                     <ListView.ItemContainerStyle>
                         <Style TargetType="ListViewItem">
                             <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
                             <Setter Property="Padding" Value="0"></Setter>
                         </Style>
                     </ListView.ItemContainerStyle>
                 </ListView>
                 <TextBox Text="{Binding setting_values[0], Mode=TwoWay}"></TextBox>
             </StackPanel>
        </DataTemplate>
    </Pivot.ItemTemplate>
</Pivot>

Does anyone have an idea what i did wrong and why one Twoway binding works and the other doesn't

Thanks for your help in advance.


Solution

  • I solved it with this setup:

    // SETTING.idl
    runtimeclass SETTING : Windows.UI.Xaml.Data.INotifyPropertyChanged
    {
        String description;
        String value;
    }
    
    //SETTING_VIEWMODEL.idl
    import "SETTING.idl";
    
    runtimeclass SETTINGS_VIEWMODEL
    {
        Windows.Foundation.Collections.IObservableVector<SETTING> settings_vector{ get; };
    }
    
    //SETTINGS_PAGE.idl
    import "SETTINGS_VIEWMODEL.idl";
    
    [default_interface]
    runtimeclass SETTINGS_PAGE : Windows.UI.Xaml.Controls.Page
    {
        SETTINGS_PAGE();
        SETTING_VIEWMODEL settings{ get; };
    }
    

    Now you can bind the values with a TwoWay Binding:

    //SETTINGS_PAGE.xaml
    <Listview ItemsSource="{x:Bind settings.settings_vector, Mode=OneWay}">
        <ItemsControl.ItemTemplate>
            <DataTemplate x:DataType="local:SETTING">
                <Grid Height="40">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{x:Bind description, Mode=OneWay}" Grid.Column="0" VerticalAlignment="Center" FontSize="18"></TextBlock>
                    <TextBox Text="{x:Bind value, Mode=TwoWay}" Grid.Column="1" VerticalAlignment="Center" FontSize="18"></TextBox>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </Listview>