Laden...

TextBlock o.ä. mehrfach auf Oberfläche anzeigen

Erstellt von csOffroad vor 8 Jahren Letzter Beitrag vor 8 Jahren 1.351 Views
C
csOffroad Themenstarter:in
64 Beiträge seit 2009
vor 8 Jahren
TextBlock o.ä. mehrfach auf Oberfläche anzeigen

Hi Leute,

habe hier irgendwie noch ein Verständnisproblem. Ich habe im Hauptfenster eine ObservableCollection<UIElement>, in die ich Textblöcke einfüge. Auf der Oberfläche möchte ich die Elemente einmal in zwei normalen ListBoxen anzeigen und des weiteren auch in einer ListBox, die in einem UserControl sitzt. Dazu habe ich in dem UserControl eine DependencyProperty gesetzt, die sich ebenfalls auf die ObservableCollection hängt.
Der Effekt ist nun der: Irgendeiner von den drei Listboxen krallt sich die Elemente, die anderen beiden bekommen sie nicht mehr. Kommentiere ich eine Listbox aus, ist es irgendeine andere, die sich jetzt die Elemente krallt.
Ändere ich den Typ der ObservableCollections von UIElement auf string, kriegen es alle!
Bitte helft mir, wie kann ich einen Referenztyp auf der Oberfläche mehrfach anzeigen?
Dankeschön! 😃

MainWindow:


<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" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:WpfApplication1="clr-namespace:WpfApplication1" d:DesignHeight="350" d:DesignWidth="525" SizeToContent="WidthAndHeight"
        x:Name="basee"
        >
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition/>
      <ColumnDefinition/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <ListBox x:Name="lb1" Grid.Column="0" ItemsSource="{Binding Childs}"/> 
    <ListBox x:Name="lb1a" Grid.Column="1" ItemsSource="{Binding Childs}"/>
    <WpfApplication1:Tb2 x:Name="tb2" Grid.Column="2" Childs2="{Binding Childs, RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}}" />
  </Grid>
</Window>


using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication1
{
  public partial class MainWindow
  {
    private ObservableCollection<UIElement> _childs = new ObservableCollection<UIElement>();

    public MainWindow()
    {
      InitializeComponent();

      DataContext = this;


      Loaded += (aS, aE) =>
                {
                  for (var i = 0; i < 10; i++)
                  {
                    var tb = new TextBlock {Text = i.ToString()};
                    Childs.Add(tb);
                  }
                };
    }

    public ObservableCollection<UIElement> Childs
    {
      get
      {
        return _childs;
      }
      set
      {
        _childs = value;
      }
    }
  }
}

UserControl:


<UserControl x:Class="WpfApplication1.Tb2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
  <ListBox x:Name="lb2" Grid.Column="0" ItemsSource="{Binding Childs2}"/>
</UserControl>


using System.Collections.ObjectModel;
using System.Windows;

namespace WpfApplication1
{
  public partial class Tb2
  {
    public static readonly DependencyProperty Childs2Property =
      DependencyProperty.Register("Childs2", typeof (ObservableCollection<UIElement>), typeof (Tb2));


    public Tb2()
    {
      InitializeComponent();

      DataContext = this;
    }

    public ObservableCollection<UIElement> Childs2
    {
      get
      {
        return (ObservableCollection<UIElement>) GetValue(Childs2Property);
      }
      set
      {
        SetValue(Childs2Property, value);
      }
    }
  }
}

C
180 Beiträge seit 2011
vor 8 Jahren

Hi,
pack in die Observable keine Gui Elemente. Sondern nur die Daten selbst, in dem fall also die strings.
Im Xaml fügst du der ListBox dann ein DataTemplate hinzu ... da wird definiert wie die Daten Dargestellt werden -> also definierst du da die TextBox

so müsste es klappen

T
314 Beiträge seit 2013
vor 8 Jahren

Hi,

binde nicht deine Liste an eine Liste von UIElements sondern an eine Liste welche deine darzustellenden Informationen hält.

Die Darstellung des Typs definierst du dann im XAML. z.B.


<ListBox x:Name="lb1" Grid.Column="0" ItemsSource="{Binding Childs}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding MeinWert}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

771 Beiträge seit 2009
vor 8 Jahren

@csOffroad: Ich denke es liegt daran, daß ein UIElement nur genau einen Parent haben kann, d.h. die letzte Anzeige gewinnt.

Daher nutze den von den beiden anderen vorgeschlagenen (und vorgesehenen) Weg...

C
csOffroad Themenstarter:in
64 Beiträge seit 2009
vor 8 Jahren

Herzlichen Dank euch, das mit dem einen visuellen parent hab ich verstanden und eine Lösung finden können 😃