0

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}"/>
Sonic Joe
  • 13
  • 3
  • It's a bit hard to understand exactly what you want. Do you want to have a TextBox which cannot be modified by the user, but the Comments property value will change and when it does you want the bound TextBox to scroll to the bottom? – Decade Moon Nov 02 '16 at 10:02
  • That's right, the TextBox cannot be modified by the user but as the Comments property accumulates and it exceeds the TextBox, I want the TextBox to scroll to the bottom so that it shows the last line. This is the motivation behind wanting to bind to TextBox. Not sure how to implement scroll-to-the-bottom behavior in this case where TextBox is embedded inside ListView. – Sonic Joe Nov 02 '16 at 13:57

1 Answers1

1

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.

Community
  • 1
  • 1
Paweł Słowik
  • 308
  • 2
  • 11
  • Because TextBox has the TextChanged event where I can implement the scroll-to-the-bottom effect, as shown in your link. I am not sure how to implement scroll-to-the bottom behavior in this scenario where TextBox is embedded inside ListView. – Sonic Joe Nov 02 '16 at 13:52
  • You can use events from ObservableCollection. – Paweł Słowik Nov 05 '16 at 16:28
  • Sorry, posted the comment without pasting link - http://stackoverflow.com/questions/2006729/how-can-i-have-a-listbox-auto-scroll-when-a-new-item-is-added – Paweł Słowik Nov 05 '16 at 16:29