Hi,
habt vielen Dank für Eure Antworten. Ich werde die Lib-API so aufbauen, dass alle Logger optional angegeben werden können. Auch wenn es inzwischen einen NullLogger gibt, ist stets mehr Aufwand mit einer erzwungenen Abhängigkeit generiert.
Mich haben aber besonders die Argumente zum Thema Performance und zusätzlicher Implementierungsaufwand überzeugt.
Hallo,
Ich erfrage hier mal Eure Meinung zum Thema API einer Lib-Assembly.
Ich nutze in meinen Klassen einen Logging Provider. Dieser wird injiziert oder kann injiziert werden.
D.h. in einigen Klassen ist er als nullable ausprogrammiert. In anderen Klassen hingegen ist der ILogger nicht nullable. Insbesondere, weil dort durch das Log wichtige Information im Fehlerfall ausgegeben werden. In den Klassen mit nullable kommen ausschließlich optionale Informationen, die nicht zur angeforderten Schnittstellenfunktion beitragen.
Der Sinn beim nullable Typ ist hier, eine Nutzung der Klasse auch zu ermöglichen, wenn kein Logging-Provider für die nutzende App definiert ist.
Jetzt zum Kern meiner Frage:
Macht es mehr Sinn die nullable ILogger rauszuschmeissen und den Anwender der Klasse zum Liefern eines Logging Provider zu zwingen? Er könnte den Logger ja schließlich auch mocken, wenn er keinen Logging-Provider liefern möchte...
Bin gespannt auf Eure Meinungen.
Viele Grüße Sprotti
Ok, das war nun wirklich mal einfach.
VS zeigte im Projektmappen-Explorer in den betreffenden Projekten jeweils einen obj Ordner mit weißem Balken auf rotem Kreis.
Ich habe alle diese obj Ordner komplett abgelöscht und die "doppelte Member - Fehler" waren erledigt.
Leider kann ich nicht sagen, wodurch die obj Ordner entstanden sind und warum sie diese Fehlermeldungen verursachen.
Vielleicht hat da noch jemand Aufklärung parat.
Hallo zusammen,
wenn jemand einen Hinweis geben könnte, warum VS sowas tut...
CS0102 kommt aus der MainWindow.xaml für den Eintrag:
<Button x:Name="btnRestore" Content="Restore"...
zugehörig dazu meint der Compiler CS0229 aus der MainWindow.g.i.cs
Mehrdeutigkeit zwischen "MainWindow.btnRestore" und "MainWindow.btnRestore" für den Eintrag:
public partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector {
void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target){
switch (connectionId)
{
...
case 3:
this.btnRestore = ((Sytem.Windows.Controls.Button)(target));
return;
...
}
this._contentLoaded = true;
}
Kann mir jemand sagen, wie ich VS davon überzeuge, dass es selbst den Fehler macht 😉?
Oder sitzt der Fehler evtl. doch wieder vorm Rechner?
Danke für die Links. Mehr ist doch auch nicht erforderlich. Wenn ich die Antwort gefunden habe kann ich sie ja dann immer noch für das Forum aufbereiten. (Um das Thema rund zu machen=)
Es hat auch funktioniert. Ich hatte nur verpasst, dass ich aus Probierwut noch den DataContext auf den Key gesetzt hatte.
<DockPanel LastChildFill="True" DataContext="OverviewVM">
Hab ihn entfernt und nun läuft es auch.
⚠ An alle WPF Anfänger wie mich... weniger ist mehr. Der notwendige Rest wird von WPF Magic erledigt. ⚠
Problem ist gelöst. Vielen Dank Euch.
Eine Frage hätte ich aber doch noch. Wie wird denn das ActiveViewModel aus dem MainViewViewModel zum DataContext für die View. Welche Stelle in meinem Code sorgt dafür? Blöd wenn etwas funktioniert was du machst und du weißt nicht warum... Hat das was mit dem DataTemplate zu tun? Wird der DataContext der MainView ergänzt oder geändert? Ich habe den DataContext für die MainView eigentlich nur einmal im Code gesetzt.
<Window.DataContext>
<vm:ViewModelMainPage />
</Window.DataContext>
Von den anderen ViewModels habe ich eigentlich nirgendwo sonst deklariert, dass sie als DataContext für ihre View dienen sollen.
Ach ja, und es wäre natürlich arg hilfreich wenn IntelliSens weiterhin dazu gebracht werden könnte vernünftige Binding Vorschläge zu liefern. Wie muss ich denn MarkupExtension anwenden?
Warum denn? Das ist genau der Knackpunkt,...
Darüber kannst Du von der View aus aufs VM zugreifen.
Brauche ich denn keinen Key für die Bindungen in der View. Was gebe ich den Bindungen als Source mit wenn ich in den Resources den Key OverviewVM nicht mehr deklariere? Bisher habe ich ja die Bindungen der View so geschrieben...
<Button.Command>
<Binding Source="OverviewVM" Path="CmdApplyPLCSettings"/>
</Button.Command>
Wenn ich die Deklaration in Resources und Source in den Bindungen einfach weglasse, scheint keine Datenbindung für die Felder zu existieren.
Hallo zusammen,
ich habe in CodeProject und hier im Forum schon viel Hilfreiches zum Thema MVVM gefunden und umgesetzt, bin aber nun auf ein ärgerliches Hindernis gestossen.
Situation:
View:
Ich habe eine MainView mit einem ContentControl und Buttons die den anzuzeigenden Inhalt (UserControl) in dieser umschalten. Jedes dieser UserControl entspricht also einer View mit einem dazu gehörenden ViewModel.
<Window.Resources>
<DataTemplate x:Key="OverviewTemplate" DataType="vm:ViewModelOverview">
<local:Overview/>
</DataTemplate>
<helper:ViewTemplateSelector x:Key="VTemplateSelector"
overviewVM="{StaticResource OverviewTemplate}"
infoVM="{StaticResource InfoTemplate}"
/>
</Window.Resources>
<Grid>
<ContentControl Content="{Binding ActiveViewModel}" ContentTemplateSelector="{StaticResource VTemplateSelector}"/>
</Grid>
ViewModel:
Im MainViewViewModel wird bei der Umschaltung der gebundenen ActiveViewModel Property das ViewModel der anzuzeigenden View zugewiesen. Im Konstruktor des MainViewViewModels werden alle ViewModels aller möglichen Views instanziiert.
public ViewModelMainPage()
{
#region create ViewModel Instances
_overviewViewModel = new ViewModelOverview();
_infoViewModel = new ViewModelInfo();
#endregion
}
private ViewModelBase _activeViewModel;
public ViewModelBase ActiveViewModel
{
get { return _activeViewModel; }
set { _activeViewModel = value; RaisePropertyChanged( "ActiveViewModel" ); }
}
In der entsprechenden View wird das entsprechende ViewModel als Resource hinterlegt.
<UserControl.Resources>
<vm:ViewModelOverview x:Key="OverviewVM"/>
</UserControl.Resources>
Nun wird also stets die dem gerade selektierten ViewModel entsprechende View im ContentControl angezeigt. Aber...
Herausforderung:
wenn ich von einer View in die andere wechsele wird jedes Mal beim erneuten Anzeigen eine neue Instanz der View erzeugt und was noch schlimmer ist, auch eine neue Instanz des zugehörigen ViewModel. Im CallStack ist ersichtlich, dass ausgehend von InitializeComponent der View der Konstruktor des zugeordneten ViewModels aufgerufen wird.
Frage:
Wie stelle ich meinen Code so um, dass die View stets auf die eine Instanz des ViewModel zugreift, welche in dem Konstruktor des MainViewViewModel beim Anwendungsstart erzeugt wurde? Die Instanziierung der ViewModel muss auch nicht unbedingt im MainViewViewModel erfolgen. Ich wäre hier für Vorschläge dankbar wo ein besserer Ort dafür wäre.
Danke Th69, werd gleich mal probieren ob es so funktioniert. Hm, macht sicher das Reindenken einfacher wenn man sich an Coding Conventions hält... werd es beim nächsten Mal versuchen zu beachten. Sorry
Hallo zusammen...
Ich versuche nach der im Netz gefundenen Anleitung Data Binding for Windows Forms eine Datenbindung zu erstellen. Ich habe nach einiger Suche zu Combobox und Datenbindung die Hoffnung verloren in vorhandenen Beiträgen eine sinnvolle Antwort auf mein Problem zu finden. Daher nun der Versuch mit einem eigenen Beitrag.
Test: Windows Form soll Combobox an data binden. Dabei soll ein enum die Quelle für die Items sein und die selected property die Auswahl der Combobox wiederspiegeln.
Problem: Was fehlt noch um die Datenbindung zum Funktionieren zu bewegen?
Hier der soweit erzeugte Code zu data (SelEnum ist halt mein Enum)
public class data
{
public data()
{
}
public string selected { get; set; }
public Array Selection { get { return Enum.GetValues(typeof(SelEnum)); } }
public string defaultval { get { return SelEnum.dasDritte.ToString(); } }
}
nun hier noch die für die Datenbindung wesentlichen stellen aus InitializeComponent...
//Initialize
this.components = new System.ComponentModel.Container();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit();
//ComboBox
this.comboBox1.DataSource = this.bindingSource1;
this.comboBox1.DisplayMember = "selected";
//BindingSource
this.bindingSource1.DataSource = typeof(comboboxbindingtest.data);
//Label
this.label1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.bindingSource1, "defaultval", true));
//Form
((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit();
wie ihr seht habe ich versucht über den Designer die Datenbindung herzustellen. Program.cs und Form.cs sind unverändert geblieben.
Ich hoffe es hat jemand Lust sich reinzudenken der mich Nostalgiker unterstützen möchte. 😉
Vermutung: Ich sehe nirgends eine Instantiierung von data. Ich wüsste aber auch keinen Punkt wo ich eine data-Instanz der Datenbindung noch bekannt machen könnte...