How to Display ObservableCollection in a UserControl

后端 未结 4 1431
滥情空心
滥情空心 2021-01-15 13:48

I\'m new to WPF and I\'ve found some similar questions but can\'t quite figure out the last part. I have a ViewModel with an ObservableCollection that contains error messag

相关标签:
4条回答
  • 2021-01-15 14:22

    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:

    enter image description here

    0 讨论(0)
  • 2021-01-15 14:22

    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.

    0 讨论(0)
  • 2021-01-15 14:22

    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();
        }
    }
    
    0 讨论(0)
  • 2021-01-15 14:22
    <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>
    
    0 讨论(0)
提交回复
热议问题