Laden...

Forenbeiträge von sugar76 Ingesamt 69 Beiträge

14.06.2018 - 15:18 Uhr

Erstmal danke für die Antworten.

Ich habe es jetzt so umgesetzt, dass ich ich immer INotifyDataErrorInfo verwende und bei einfachen Validierungen Task.FromResult() nutze.

Ich finde das Programmiermodell bei IDataErrorInfo einfacher. Aber in vielen Fällen wird halt asynchrone Validerung benötigt ...

13.06.2018 - 22:39 Uhr

Hallo,

mich würde mal interessieren, wie ihr zum Thema asynchrone Validierung mittels INotifyDataErrorInfo steht.

Mein "Problem" dabei: die GUI während der Validierung nicht blockieren zu lassen, ist ja an sich sinnvoll.
Aber ich will doch nicht jede Validierung eines Eingabefelds (z.B. prüfen, ob überhaupt etwas eingegeben wurde) in einem separaten Thread durchführen.

Hierzu ein Beispiel:
View:

<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True}" />

Validierung im ViewModel:


private async Task<string> ValidateName()
{
    bool empty = await Task.Run(() => Name != null && Name.Length > 0);
    return empty ? "Bitte Wert eingeben" : null;
}

In diesem Beispiel wird bei jeder Tastatureingabe Task.Run() aufgerufen. Der Aufruf von Task.Run() kostet mehr Ressourcen als ein synchroner Aufruf.

Wie macht Ihr das? Nutzt ihr asynchrone Validierung mit INotifyDataErrorInfo? Wie sind Eure Erfahrungen bzgl. Ressourcenverbrauch? Ein "Mischbetrieb" von asynchroner/synchroner Validierung ist m.E. nicht ohne weiteres möglich ...

Gruß

05.06.2018 - 14:05 Uhr

Interessant wäre, was in deinem Output steht.

In der Ausgabe steht nichts. Es wird kein Fehler ausgegeben, dass das Binding nicht aufgelöst werden konnte.

05.06.2018 - 10:12 Uhr

Hallo.

ich verwende ein DataGrid innerhalb eines UserControls. In diesem DataGrid verwende ich wiederum ein UserControl controls:DataGridProgressBar als Hinweis, dass die anzuzeigenden Daten noch geladen werden:


<UserControl>
     <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ItemListView}">
            <DataGrid.Background>
                <VisualBrush Stretch="None">
                    <VisualBrush.Visual>
                        <StackPanel>
                            <controls:DataGridProgressBar LoadingMessage="Daten werden geladen ..."
                                             EmptyDatasetMessage="No Records Found"
                                             RecordCount="{Binding Path=RecordCount}"
                                             LoadInProgress="{Binding Path=Loading}" />
                        </StackPanel>
                    </VisualBrush.Visual>
                </VisualBrush>
            </DataGrid.Background>
            <!-- ... -->
      </DataGrid>

Nun würde ich gerne dieses "Verhalten" in einem globalen Style hinterlegen (in App.xaml):


<Application>
    <Application.Resources>
        <Style x:Key="ListViewStyle" TargetType="DataGrid">
            <Setter Property="Background">
                <Setter.Value>
                    <VisualBrush Stretch="None">
                        <VisualBrush.Visual>
                            <StackPanel>
                                <controls:DataGridProgressBar LoadingMessage="Daten werden geladen ..."
                                        EmptyDatasetMessage="No Records Found"
                                        RecordCount="{Binding Path=RecordCount}"
                                        LoadInProgress="{Binding Path=Loading}" />
                            </StackPanel>
                        </VisualBrush.Visual>
                    </VisualBrush>
                </Setter.Value>
            </Setter>
        </Style>

Wenn ich mein DataGrid nun dahingehend ändere:


<UserControl>
    <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding ItemListView}" Style="{StaticResource ListViewStyle}">
<!-- ... -->

... funktionieren die Bindings RecordCount="{Binding Path=RecordCount} und LoadInProgress="{Binding Path=Loading}" nicht mehr. Der Grund wird wohl sein, dass der DataContext des ViewModels in der globalen App.xaml nicht mehr zur Verfügung steht.

Was kann man da machen? Kann man die Bindings in der App.xaml irgendwie "umbiegen", so dass diese den DataContext des aktuell verwendeten ViewModels nutzen?

Gruß ...

04.06.2018 - 14:09 Uhr

Vielen Dank für die tolle Erklärung. Ich komme aus der Java-Welt, da ist das async/await-Programmiermodell zunächst etwas ungewohnt...

04.06.2018 - 12:34 Uhr

Supi, danke für den Hinweis.

Ich gebe mal wieder, wie ich es verstanden habe:*Der Task wird mittels Task.Run(() => ...) in einem separaten Thread ausgeführt. *Der Code, welcher mit dem await beginnt, wird im GUI-Thread ausgeführt, sobald der der Task abgearbeitet und der GUI-Thread idle ist

Ist das korrekt?

04.06.2018 - 11:20 Uhr

Hallo allerseits,

ich hätte mal ne Verständnisfrage zur Aktualisierung von Daten im View aus einen Background-Task heraus.

DataGrid:


<DataGrid ItemsSource="{Binding ItemListView}">
            <DataGrid.Columns>
                <!-- ... Spalten ... -->
            </DataGrid.Columns>
</DataGrid>

ViewModel für das DataGrid:


public class DokumentListViewModel : ListViewModelBase<DokumentListItemViewModel>
{
        public DokumentListViewModel()
        {
            RefreshAsync(); // Hier werden die anzuzeigenden Daten geladen ...
        }

        public override IEnumerable<DokumentListItemViewModel> GetItems()
        {
            return DokumentService.GetDokumente();
        }
}

public abstract class ListViewModelBase<T> : ViewModelBase
{
        public RangeEnabledObservableCollection<T> ItemList { get; protected set; }

        public ListCollectionView ItemListView { get; protected set; }


        public ListViewModelBase()
        {
            ItemList = new RangeEnabledObservableCollection<T>();
            ItemListView = new ListCollectionView(ItemList);
        }


        public virtual void Refresh()
        {
            ItemList.Clear();
            IEnumerable<T> items = GetItems();
            ItemList.InsertRange(items);
        }


        public async void RefreshAsync()
        {
            ItemList.Clear();
            IEnumerable<T> items = await Task.Run(() => GetItems());
            ItemList.InsertRange(items);
        }
}

Das funktioniert soweit wunderbar. Der Inhalt des Datagrids wird asynchron erzeugt, so dass der View unabhängig vom Inhalt gerendert werden kann.

Ersetze ich den Aufruf im Konstruktor von DokumentListViewModel wie folgt:


        public DokumentListViewModel()
        {
            // RefreshAsync();
            Task.Run(() => Refresh());
        }

... erhalte ich beim Anzeigen eines Views einen Fehler, weil die Änderungen "... nicht von einem Dispatcher-Thread aus erfolgen".

Meine Frage: warum erhalte ich diesen Fehler nicht bei Verwendung von RefreshAsync()? In beiden Fällen wird doch aus einem seperaten Thread heraus der View geändert?

Gruß

27.02.2018 - 16:22 Uhr

Nach mehrmaligem Neu-Kompilieren und Neustarten von VS ging es dann. Wahr wohl ein Bug in VS.

Hat sich also erledigt ....

27.02.2018 - 15:56 Uhr

Hatte das Problem auch, weil die Dateien mit einem anderen Editor als VS bearbeitet wurden. Besten Dank für die Lösung!

26.02.2018 - 11:25 Uhr

Hallo allerseits,

ich habe eine ComboBox als Custom Control erstellt, bestehend aus den Dateien AutoComplete.xaml und AutoComplate.xaml.cs

Standardnamespace des Projekts ist Betreuung.

Der Inhalt von AutoComplete.xaml.cs ist angehängt.

Inhalt von AutoComplete.xaml:


<ComboBox x:Class="Betreuung.View.Controls.AutoComplete"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    IsEditable="True" StaysOpenOnEdit="True" IsTextSearchEnabled="False"
    LostFocus="ComboBox_LostFocus" SelectionChanged="ComboBox_SelectionChanged" Loaded="ComboBox_Loaded">

</ComboBox>

Beim Erstellen kriege ich für AutoComplete.xaml die Fehlermeldung:> Fehlermeldung:

Der Typ- oder Namespacename "View" ist im Namespace "Betreuung.View.Betreuung" nicht vorhanden. (Möglicherweise fehlt ein Assemblyverweis.)

Lasse ich die Event-Handler aus AutoComplete.xaml weg, verschwindet der Fehler


<ComboBox x:Class="Betreuung.View.Controls.AutoComplete"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    IsEditable="True" StaysOpenOnEdit="True" IsTextSearchEnabled="False">

</ComboBox>

Mir gibt der Fehler Rätsel auf.

Hat irgendjemand eine Idee, wo das Problem liegt?

08.02.2018 - 18:26 Uhr

Hallo allerseits,

in einem Formular ist folgender Button


<Button Content="Speichern" IsEnabled="{Binding Path=Valid, Mode=OneWay}" Click="ButtonSave_Click" />

In meinem ViewModel gibt es die Eigenschaft Valid, die bestimmt ob die Eingabedaten im Formular gültig sind:


public bool Valid
{
       get
       {
           return (Anrede == 1 || Anrede == 2) && !string.IsNullOrWhiteSpace(Name);
       }
}

Der ClickHandler:


private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
    // mache etwas und dann schließe Fenster ...
    Window.GetWindow(this).Close();
}

Den ClickHandler verwende ich deswegen, weil beim Klick auf den Button das umgebende Window geschlossen werden soll. Das Window kann ich bequem im View abgreifen. Bei einem Command-Binding über ein ViewModel hätte ich kein Zugriff auf das Window-Objekt.

Jetzt habe ich aber das Problem, dass der Button nicht enabled wird, wenn sich die Valid-Eigenschaft ändert. Wie kann ich das erreichen, dass die IsEnabled-Eigenschaft über ein Binding gesteuert wird, ich aber kein Command-Binding verwende?

Gruß

12.01.2018 - 14:10 Uhr

also ich würde behaupten einen eigenen Mailclient zu schreiben läuft schon unter fahrlässig - würde ich gar nicht erst erwägen.

Ja, der Aufwand ist wohl zu hoch.

Mit Outlook kann man sich zwar verbinden - verlassen als DB würde ich mich darauf allerdings nicht - Archivierung wird (wenn diese nicht bereits eingesetzt wird) dann Probleme verursachen

Idee ist, alle neuen Emails im Posteingang im msg-Format einer eigenen DB zu speichern. Damit bin ich unabhängig von Archivierung, etc. Aufpassen muss man, wenn die Mails per Regeln direkt nach Eingang in einen anderen Ordner verschoben werden. Für diesem Fall müsste der Nutzer die Möglichkeit haben, Ordner anzugeben, die von meiner Anwendung nach neuen Mails durchsucht werden.

11.01.2018 - 16:34 Uhr

Hallo allerseits,

das passt hier nicht 100% ins Office-Forum, aber woanders passt es irgendwie noch weniger.

Ich benötige in einer (geplanten) WPF-Anwendung eine Email-Integration. Die Anwendung besteht u.a. aus einer Adressdatenbank. Anforderung ist, dass ein- und ausgehende Emails mit bestehenden Adressdatensätzen verknüpft werden. Weiterhin ist Teil der Anforderung, aus der Anwendung heraus Emails zu schreiben und zu beantworten. Es wird IMAP verwendet.

Jetzt stehe ich vor der Frage:

  1. implementiere ich für die Anwendung einen eigenen Email-Client oder
  2. nutze ich Outlook zum Schreiben/Beantworten von Emails.

Bei 2) würde ich mittels NetOffice Emails aus Outlook einlesen, in der DB speichern und mit den bestehenden Adressdatensätzen verknüpfen.

Beide Varianten überzeugen mich nicht so richtig. Bei Variante 1) ist der Entwicklungsaufwand sehr hoch (IMAP-Ordner, Verfassen/Beantworten, Textformatierung, etc.) bei Variante 2) habe ich das Problem, in meiner Anwendung eine zweite Email-Datenbank aufzubauen, die mit der Zeit zwangsläufig mit der realen IMAP-Struktur auseinanderläuft.

Frage: wie würde Ihr das umsetzen bzw. hat jemand von Euch schon mal in einer Anwendung eine Email-Funktionalität eingebaut und wenn ja, wie?

Gruß

09.12.2017 - 10:45 Uhr

Erstmal vielen Dank für alle Antworten.

Ich fasse mal zusammen:

  1. Code per obfuscation schützen bietet ein Plus an Sicherheit, aber mehr auch nicht.
  2. Zugangsdaten zu Datenbanken, etc. lassen sich am besten dadurch schützen, dass man den Rechner absichert, auf dem die Zugangsdaten liegen. Hier ist die Verwendung einer separaten Zugriffsschicht (REST Service o.ä.) auf einem eigenen Server und den Zugriff zur Datenbank bereitstellt, "sicherer" als wenn die Zugangsdaten direkt auf dem Client Rechner liegen.
07.12.2017 - 18:35 Uhr

Das Thema wurde ungefähr 42986423490324234 mal besprochen - und das vorsichtig geschätzt.

Da hast Du Recht... ich wollte einfach eine Diskussion eröffnen, der Stand der Technik kann sich ja mit der Zeit ändern.

Wenn Du ConnectionStrings brauchst, dann scheint es schon ein grundlegender Fehler bzgl. Architektur zu sein, dass die Anwendung direkt auf einen Datenbankserver zugreift und nicht über einen Service (zB. REST) dazwischen.

Bzgl. Architektur gebe ich Dir nochmal Recht. Es gibt aber Szenarien, in denen die Software beim Kunden läuft und dann läuft beim Kunden auch der REST-Service. Egal, welche Architektur man verwendet, irgendeine Komponente hat den Zugriff zur Datenbank und dort steht dann ein Connection-String.

07.12.2017 - 18:07 Uhr

Hallo allerseits,

ich habe zwar schon viel entwickelt, aber wenig Erfahrungen damit, wie ich von mir entwickelte Software vor unerlaubtem Zugriff schützen kann. Das gilt insbesondere dann, wenn die Software beim Kunden installiert ist, also nicht auf einem von mir betriebenen Server läuft.

Das betrifft folgendes:
* Wie kann ich sicherstellen, dass der Code nicht per Reverse Engineering ausgelesen werden kann?
* Wie kann ich verhindern, dass sensible Daten, wie z.B. Connection-Strings für Datenbanken, nicht im Klartext in irgendwelchen Config-Dateien landen, sondern verschlüsselt werden?

Wie sind Eure Erfahrungen in diesem Bereich?

Grüße,

Abid

22.11.2017 - 17:39 Uhr

Besten Dank für die Antworten.

Zusammenfassend kann man wohl sagen, dass MS SQL Server am besten mit Visual Studio, Linq, etc. harmoniert (logisch) und als kostengünstige Alternative PostgreSQL dem Einsatz von MySQL vorzuziehen ist.

Gruß, Abid

22.11.2017 - 11:04 Uhr

Hallo allerseits,

ich plane gerade ein Softwareprojekt, eine klassische Desktopanwendung mit WPF.

Die Anwendung ist auf den Client-Rechnern installiert, die Datenbank läuft auf einem eigenen Server. Geplant ist eine Instanz mit Windows Server, auf dem MS SQL Server läuft.

Hauptgrund für MS SQL Server: ich erwarte eine reibungslose Integration in Visual Studio und anderen Technologien wie EntityFramework oder Linq.

Die Lizenz für MS SQL Server kostet ein paar Tausend Euro. MS SQL Server Express ziehe ich wg. der RAM-Limitierung nicht in Betracht. MySQL hat im Gegenzug den Vorteil, dass es kostenlos zu haben ist.

Ich habe MySQL bisher in PHP- und Java-Projekten eingesetzt. Wie sind eure Erfahrungen beim Zusammenspiel von MySQL und Microsoft Technologien? Ist ein reibungsloses Zusammenspiel mit Visual Studio sowie EntityFramework bzw. Linq zu erwarten? Oder würdet Ihr abraten?

Grüße,

Abid

19.10.2017 - 15:16 Uhr

Hallo allerseits,

ich versuche gerade herauszufinden, ob man das Anzeigen/Bearbeiten eines Word-Dokuments direkt in eine Webseite integrieren kann.

Dabei bin ich auf WOPI gestoßen, ich werde aber auch nach einigem Lesen nicht so richtig schlau daraus ...

  1. Wie funktioniert das Ganze überhaupt? AFAIK muss man einen WOPI Server und einen WOPI Client implementieren. Oder braucht man dafür einen Sharepoint Server? Irgendeine Komponente muss ja den HTML/Javascript Code für den Editor ausliefern.

  2. Ist WOPI noch aktuell und wird diese Technologie von Microsoft aktuell weiterentwickelt?

Hat jemand von Euch Erfahrungen damit? Bin für jede Hilfe dankbar...

Gruß,

Abid