Sonic Joe
Sonic Joe

Reputation: 13

Binding ObservableCollection<Item> To TextBox (UWP)

I want to achieve one-way binding from an ObservableCollection of "struct-like" items to a TextBox that has a TextChanged event. The idea is that as the Comments field of Item accumulates in the TextBox, the TextBox scroll down automatically so that the last line is always in view. The collection is bound to a ListView but I want it bound read-only to the TextBox. I would prefer not to add another method in ResultViewModel but do it in XAML. How would I go about in doing this? TIA

// ViewModel

public class Item
    {        
        public string First { get; set; }

        public string Last { get; set; }

        public string Comments { get; set; }
    }

public class ResultViewModel
    {
        private ObservableCollection<Item> items = new ObservableCollection<Item>();                                          

    public ObservableCollection<Item> Items { get { return items; } }

        // member functions
    }

public ResultViewModel ViewModel { get; set; }

// What I have

            <ListView x:Name="myListView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"                      
                  ItemsSource="{x:Bind ViewModel.Items}">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="local:Item">
                        <StackPanel>
                            <TextBox Text="{x:Bind First}"/>
                            <TextBlock Text="{x:Bind Last}"/>
                            <TextBlock Text="{x:Bind Comments}"/>
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

// What I want

<TextBox Text="{x:Bind Comments}"/>

Upvotes: 0

Views: 691

Answers (1)

Paweł Słowik
Paweł Słowik

Reputation: 308

I'm afraid you can't do it with XAML alone. You can create a behavior which will listen to events and add lines to the textbox when the collection is modified.

Dirty example, you will need to include Microsoft.Xaml.Behaviors.Uwp.Managed package:

public class CommentsBehavior : Behavior
{
    public ObservableCollection<string> Comments ... // you will need to make it a dependency property

    protected virtual void OnAttached()
    {
        Comments.CollectionChanged += OnCollectionChanged;
    }

    protected virtual void OnDetaching()
    {
        Comments.CollectionChanged -= OnCollectionChanged;
    }

    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach(string newItem in e.NewItems)
            {
                ((TextBox)AssociatedObject).Text = ((TextBox)AssociatedObject).Text + '\n' + newItem;   
            }
        }
    }
}

And for scrolling - UWP C# Scroll to the bottom of TextBox

But why do you want to use textbox for this? Using list makes more sense.

Upvotes: 1

Related Questions