Laden...

UserControl/CustomControl - übergebenes DataGrid - Properties auslesen, Änderungen determinieren

Erstellt von Birne vor 13 Jahren Letzter Beitrag vor 13 Jahren 4.625 Views
B
Birne Themenstarter:in
67 Beiträge seit 2009
vor 13 Jahren
UserControl/CustomControl - übergebenes DataGrid - Properties auslesen, Änderungen determinieren

Hallo Community,

der Titel mag etwas irreführend wirken, deshalb beschreibe ich das Problem im folgenden heir etwas genauer, praxisbezogener.

Wie bekannt, gibt es unter der WPF kein BindingNavigator Tool mehr,
also habe ich versucht, mir ein eigenes UserControl, welches die Funktionalitäten eines BindignNavigators in Bezug auf ein attached DataGrid bereitstellt, zu schreiben.

Dabei habe ich folgendes Versucht.

Ich übergebe via Propertie ein DataGrid an mein BindingNavigator Control.

Die UI des Bindingnavigators ist an dieses Propertie gebunden. In meinem Fall habe ich nun begonnen die ANzahl der Items auszulesen.

Das funktioniert auch prinzipiell, doch Wenn sich die Anzahl der Items im orginalen DataGrid ändern, so reagiert die GUI auf diese Änderung nicht.

Dabei handelt es sich doch nur um eine Referenz die ich übergebe ?
Warum bekommt die BindingNavigator Klasse die Änderung nicht mit ?

Hier die Sourcen.

Die BindingNavigator Klasse, des UserControls.


/// <summary>
    /// Interaction logic for BindingNavigator.xaml
    /// </summary>
    public partial class BindingNavigator : UserControl, INotifyPropertyChanged
    {
        /// <summary>
        /// reference to the dataGrid to work on
        /// </summary>
        private DataGrid dataGrid;

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Constructor
        /// </summary>
        public BindingNavigator()
        {
            InitializeComponent();
        }

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

        public DataGrid DataGrid
        {
            set 
            {
                this.dataGrid = value;
                OnPropertyChanged("DataGrid");
            }

            get 
            {
                return this.dataGrid;
            }
        }
    }

Die dazugehörige XAML (nicht komplett, jeweils auf meines erachtens wichtige beschränkt)


<UserControl x:Class="UserControls.BindingNavigator"
             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" Width="300" Height="50">
    <Grid x:Name="rootGrid">
            <Label x:Name="lblItemsCount" Content="{Binding Path=DataGrid.Items.Count, Mode=OneWay}"></Label>
    </Grid>
</UserControl>

In einer ganz normalen WPF Anwedung platziere ich also meinen BindingNavigator und setzte die DataGrid propertie:


        private void dataGrid1_Loaded(object sender, RoutedEventArgs e)
        {
            DataGrid dg = sender as DataGrid;
            dg.Items.Add("entry");
            dg.Items.Add("entry");

            this.bindingNavigator1.DataGrid = dg;
        }

        /// <summary>
        /// add addional entrys to test if the binding navigator update the item counter
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            this.dataGrid1.Items.Add("entry");
            this.dataGrid1.Items.Add("entry");
        }

Könnt ihr mir helfen ?
Vielen dank schon einmal 😃

Birne

5.299 Beiträge seit 2008
vor 13 Jahren

Mir scheint, du hast die Funktionsweise des Winform-BindingNavigators falsch verstanden.
Dem wird nicht ein DataGridView übergeben, sondern der wird an dieselbe DataSource gebunden, an die auch das DGV gebunden wird.

Aber das war schon unter WinForms sinnlos, denn wenn man ein DGV hat, dann kann man ja darin direkt viel besser navigieren, nämlich zum nächsten gehen, scrollen, blättern, zum Ende springen, wo der BindingNavigator nur zum nächsten gehen kann, und zum Ende springen.
V.a. zeigt das DGV ja schon wesentliche Informationen eines Datensatzes an, bevor er überhaupt angewählt ist! Das ist überaus hilfreich (na, eigentlich eine Selbstverständlichkeit), wenn man einen Datensatz _wählen _will.
Der BindingNavigator hingegen gibt nur die Position des Datensatzes preis, und die ist für den User i.a. vollkommen irrelevant.

Was ich also unter Winform schon gelegentlich empfohlen habe: "Vergesst den BindingNavigator" halte ich in WPF für ebenso gültig, und dass WPF dieses Nonsens-Control gar nicht mehr mitführt, nehme ich als Bestätigung meiner Auffassung.

Der frühe Apfel fängt den Wurm.

B
Birne Themenstarter:in
67 Beiträge seit 2009
vor 13 Jahren

Mir scheint, du hast die Funktionsweise des Winform-BindingNavigators falsch verstanden.

Ist in meinem Fall von Irrelevanz an was der BindignNavigator in Winform gebunden wurde. Ob nun an eine BindingSource oder eine DataSource.

Mir geht es darum den BindingNavigator in WPF in einem eigenen Control nachzubilden.
Wichtig in meinem Fall ist, was der Nutzer sieht/kann.
Er soll in meinem Fall durch die Datensätze im DataGrid navigieren können.


Ich stimme dir aber zu, der BindingNavigator macht zu Weilen wenig Sinn, soll aber nicht Thema dieses Threads sein.

5.299 Beiträge seit 2008
vor 13 Jahren

Nee, das ist schon wichtig, ob du mit deinem BN die gebundenen Daten steuerst (richtiger Ansatz) oder ein Datagrid manipulierst (falscher Ansatz).

Eine einfache Möglichkeit wäre, deinen BN mit einer Property CollectionViewSource Collection auszustatten.
Das ist zwar kein richtiges Binding, aber einfach zu proggen.
Die Property kann man im Xaml setzen, und wenn dann ein DG an derselben CVS hängt, sind die beiden synchron.

Also was macht ein BN?
Anzahl der verfügbaren Datensätze anzeigen.
Das kann ein an CVS.View.Count gebundenes Label leisten.

Dann noch knöpfe, mit denen CVS.View.MoveCurrentToXYZ() aufgerufen wird.
Und einen für CVS.Source.RemoveAt()
Für den New-Button müsste man mit Activator.CreateInstance(CVS.CollectionViewType,...) ein neues Item erzeugen, in die Source einhängen, und CVS.View.MoveCurrentToLast() aufrufen.

Ja, so ungefähr.

Der frühe Apfel fängt den Wurm.