How to Display ObservableCollection<string> in a UserControl

与世无争的帅哥 提交于 2019-12-01 13:29:34

May be usefull to generate FlowDocument and show this document in FlowDocumentReader. Try to start from this article: Flow Document Overview.

Example of generation:

    void ShowErrors(FlowDocumentReader reader, Exception[] errors) {
        FlowDocument doc = new FlowDocument();
        foreach (var e in errors) {
            doc.Blocks.Add(new Paragraph(new Run(e.GetType().Name)) {
                Style = (Style)this.FindResource("header")
            });
            doc.Blocks.Add(new Paragraph(new Run(e.Message)) {
                Style = (Style)this.FindResource("text")
            });
        }
        reader.Document = doc;
    }

In this example I have added some styles for text in flowdocument. PLease look at XAML:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <Style x:Key="header" TargetType="{x:Type Paragraph}">
        <Setter Property="FontWeight" Value="Bold"/>
    </Style>
    <Style x:Key="text" TargetType="{x:Type Paragraph}">
        <Setter Property="Margin" Value="30, 0, 0, 0"/>
    </Style>
</Window.Resources>
<FlowDocumentReader Name="reader">
</FlowDocumentReader>

Result:

Simplest way:

Assuming your viewmodel implements INotifyPropertyChange, create an event handler for the ObservableCollection PropertyChanged event. Create a property which aggregates all of the items in the observable colleciton into a single string. Whenever the observable collection changes, fire off a notification event for your new property. Bind to that property

public class ViewModel : INotifyPropertyChange
{
    public ViewModel()
    {
        MyStrings.CollectionChanged += ChangedCollection;
    }
    public ObservableCollection<string> MyStrings{get;set;}

    public void ChangedCollection(args,args)
    {
        base.PropertyChanged("MyAllerts");
    }

    public string MyAllerts
    {
        get
        {
            string collated = "";
            foreach(var allert in MyStrings)
            {
                collated += allert;
                    collated += "\n";
            }
        }
    }

}

I know this code is fraught with errors (i wrote it in SO instead of VS), but it should give you some idea.

Unless you have a great amount of messages a simple converter might be viable:

<TextBox IsReadOnly="True">
    <TextBox.Text>
        <Binding Path="Messages" Mode="OneWay">
            <Binding.Converter>
                <vc:JoinStringsConverter />
            </Binding.Converter>
        </Binding>
    </TextBox.Text>
</TextBox>
public class JoinStringsConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var strings = value as IEnumerable<string>;
        return string.Join(Environment.NewLine, strings);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
Waleed
<Grid Margin="6">
    <ScrollViewer VerticalScrollBarVisibility="Auto"  Height="40" Grid.Column="0" Margin="6">
        <ItemsControl ItemsSource="{Binding ErrorMessages}" >            
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                     <TextBox Text="{Binding ViewModelMemberRepresentingYourErrorMessage}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
</Grid>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!