Laden...
Avatar #avatar-2329.gif
xxxprod myCSharp.de - Experte
Programmierer Österreich\Wien Dabei seit 13.04.2006 1.378 Beiträge
Benutzerbeschreibung

Forenbeiträge von xxxprod Ingesamt 1.378 Beiträge

05.11.2012 - 15:14 Uhr

Wenn es ein SelectedDateChanged Event gibt, gibts dazu sicherlich auch eine Property die SelectedDate heißt. Wenn du an die bindest, sollte sich die DataRow auch automatisch richtig aktualiseren, wodurch das Event SelectedDateChanged wiederum überflüssig werden sollte.

Des weiteren ist die Prüfung ob "RemovedItems>0" ist nicht optimal, wenn dich eigentlich nur die AddedItems interessieren.

05.11.2012 - 14:07 Uhr

Wenn du das ControlTemplate überschreibst, musst du den darunterliegenden Controls die übergeordneten Properties mit TemplateBindings binden:


<Button Style = {staticresource ButtonStyle}>

<Style x:Key="ButtonStyle" TargetType="Button">
        <Setter Property="Template" Value="{StaticResource ButtonTemplate}"/>
</Style>

<ControlTemplate x:Key="ButtonTemplate" TargetType="Button" >
  <Button Width="120" Command="{TemplateBinding Path=Command}"> <!--So zum Beispiel-->
    <DockPanel>
      <Image DockPanel.Dock="Left" Source="pack://application:,,,/Images/Forms/Cancel_16x16.png" Width="16" Height="16"/>
       <TextBlock DockPanel.Dock="Right" Text="Abbrechen" Margin="10, 0, 0, 0" />
     </DockPanel>
   </Button>
</ControlTemplate>

Allerdings ist das schon fast die Holzhammermethode würd ich behaupten. Du könntest ja ebensogut nur das ContentTemplate des Buttons setzen, wodurch nur die Darstellung des Inhalts verändert wird, nicht aber die Funktionsweise.

Lg, XXX

05.11.2012 - 14:00 Uhr

Ich kenne mich mit Autocad-Programmierung nicht aus aber über google hab ich schnell eine vielversprechende Plattform diesbezüglich gefunden: AutoCAD .NET Developer Network

Ob du schlußendlich in VB oder C# programmierst ist der Schnittstelle egal da beides .NET ist. Und VB Beispiele kann man mit Konvertern in C# übersetzen wo man dann nur mehr ein wenig anpassen muss.

Lg, XXX

05.11.2012 - 11:22 Uhr

Ich war etwas schnell mit meiner Antwort. Deine Schwierigkeiten scheinen vom DataSet her zu rühren: Du musst irgendwo mitbekommen, wann sich ein Datensatz in deiner DataTable geändert hat. Ich weiß jetzt nicht, wo hier die beste Stelle zum Einhacken ist aber zB wurde hier schon das RowChanged Event einer DataRow erwähnt. Darüber hinaus, hat jede DataTable eine DefaultView, welche als Zwischenschicht zwischen Gui und Datatable eingezogen ist. Diese DataView hat zB ein ListChanged Event. Eventuell bringt dich das schon weiter.

Wenn du dann ein passendes Event gefunden hast, mit dem du die Änderungen mitbekommst, kannst du dann dort drinnen deine Datenbankupdates durchführen.

Lg, XXX

05.11.2012 - 11:10 Uhr

UpdateSourceTrigger=PropertyChanged, heißt nur, dass Änderungen im Control direkt ins Property geschrieben werden sollen und nicht erst beim Validating. Wenn du also im Property-Setter irgendetwas in die Datenbank speichern willst/musst, musst du dass selber implementieren. Das hat hier überhaupt nichts mit Bindings oder WPF zu tun.

Lg, XXX

02.11.2012 - 13:51 Uhr

Wie wärs mit ein wenig Eigeninitiative? Creating a custum log4net Appender

Lg, XXX

30.10.2012 - 16:10 Uhr

Ich hab Icons bei mir ausschließlich in der View. Nur in einem Fall wo ich ganz besonders flexibel sein wollte, habe ich den Namen des Images übergeben (so wie du) und auf der View damit die entsprechende Resource geladen.

Lg, XXX

29.10.2012 - 19:41 Uhr

Hallo zusammen,

ich habe gerade in einem Projekt einen DateTimeUpDown von http://wpftoolkit.codeplex.com/ in Verwendung, welches auch funktioniert nur beim ersten Laden dauert es (im Debugmodus) gut über eine Sekunde bis das Formular angezeigt wird sobald man das Control einbindet.

Hat wer Erfahrungen dazu? Im Moment versuch ich mich an so einem Hack, das Control erst nachdem das Formular geladen wurde per Trigger und ContentTemplate nachzuladen - auf diese Weise ist wenigstens das Formular zu sehen und das Control taucht dann erst eine Sekunde später auf.

Lg und Danke für jegliche Hilfe/Tipps,

XXX

19.10.2012 - 10:20 Uhr
  1. Client verschlüsselt Anfrage an Server mit dem Public-Key des Servers und sendet diese ihm.
  2. Server entschlüsselt Anfrage mit seinem Private Key und Antwortet ggf. in dem er seine Antwort mit dem Public-Key des Clients verschlüsselt und ihm übermittelt.
  3. usw. usf.

Asymetrische Verschlüsselung ist soweit ich mich erinnern kann recht rechenintensiv, weswegen man nach dem Aufbau der Verbindung, innerhalb der asymetrischen Verschlüsselung, einen generierten symetrischen Schlüssel austauschen kann, um dann anschließend symetrisch weiter zu kommunizieren.

Lg, XXX

18.10.2012 - 12:33 Uhr

Hallo uwalter,

ein ähnliches Problem hatte ich auch einmal. Das passiert, wenn man irgendwie eine Abfrage nicht komplett von oben bis unten in Linq "durchdesignen" kann sondern während der Abfrage nochmals Abfragen für Child-Elemente durchführen muss. Wenn das bei dir der Fall ist, kannst du das beheben indem du im ConnectionString den Parameter "MultipleActiveResultSets=True" hinzufügst.

Lg, XXX

18.10.2012 - 09:29 Uhr

Was mir fehlt ist der Ursprung der zwei Vektoren - oder wird automatisch 0,0 als Ursprung angenommen?

Lg, XXX

17.10.2012 - 15:49 Uhr

Sowas sollte eigentlich recht einfach nachzulesen sein und im Zweifelsfall kann man das auch schnell im Debugger testen.

Mit dem XOR Operator "^" kann man Bits umschalten:


int i = 3;

i = i^1; // i==2
i = i^1; // i==3

i = i^2; // i==1
i = i^2; // i==3

i = i^1; // i==2
i = i^2; // i==0


Lg, XXX

17.10.2012 - 15:15 Uhr

Hallo oehrle,

kannst du in einem einfachen Beispiel zeigen, wie du es in SQL lösen würdest? Deine Aussagen zu Distinct in SQL ergeben für mich leider keinen Sinn.

Lg, XXX

16.10.2012 - 16:39 Uhr

Aus der Beschreibung lässt sich leider keine Diagnose stellen. Zeig mal wie du den Singleton implementiert hast und wo die Felder initialisiert bzw. gesetzt werden.

Lg, XXX

15.10.2012 - 09:21 Uhr

Hallo kat_2403,

MVVM wäre es dann eher, wenn du das ViewModel nicht in die View integriert, sondern als eigene Klasse behalten hättest und das ViewModel keine Ahnung von der View hat. Zur Zeit ists bei dir genau anders rum und das schafft einfach unnötige Abhängigkeiten und macht auch eigentlich alles komplizierter.

Lg, XXX

12.10.2012 - 14:10 Uhr

PLinq ist keine Hexerei aber wirklich viel erhoffen darf man sich davon auch nicht. einfach nur nach dem AsEnumerable() ein AsParallel() dranhängen und schon sollten die Abfragen parallel laufen.

Lg, XXX

12.10.2012 - 13:41 Uhr

Hallo oehrle,

  • woher kommen denn deine Daten? Kann man die nicht evt. schon vorher filtern?

  • Ein DataTable hat eine RowFilter Eigenschaft mit der man vermutlich noch effizienter Filtern kann.

  • Es kann auch einen marginalen Unterschied machen wie man die Linq-Statements zusammenbaut:

  var auftrag = dataTable.AsEnumerable()
                             .Where(x => x.Field<decimal>("Auftragsnr") == auftragsNummer)
                             .OrderByDescending(c => (DateTime)c["Meldedatum"]) 
                             .Select(order => new
                                         {
                                             Auftragsnummer = order["Auftragsnr"],
                                             Arbeitsgang = order["Arbeitsgang"],
                                             Meldedatum = order["Meldedatum"]
                                         })
                             .FirstOrDefault();

Lg, XXX

12.10.2012 - 11:42 Uhr

Hallo oehrle,

so sollte es ca. funktionieren:


                var auftrag = dataTable.AsEnumerable()
                             .Where(x => x.Field<decimal>("Auftragsnr") == auftragsNummer)
                             .Select(order => new
                                         {
                                             Auftragsnummer = order["Auftragsnr"],
                                             Arbeitsgang = order["Arbeitsgang"],
                                             Meldedatum = order["Meldedatum"]
                                         })
                             .OrderByDescending(c => c.Meldedatum)
                             .FirstOrDefault();
            }

Lg, XXX

12.10.2012 - 11:00 Uhr

2 Punkte:

  1. Gewöhne dir im Umgang mit WPF bitte MVVM an. Mit Button-Events und Control-Werte-Zuweisungen im Code-Behind war bei Windows-Forms noch geläufig. Mit MVVM funktioniert das wesentlich eleganter.

  2. Verwende für XML Code bitte auch die XML-Code-Tags (das kannst du sogar noch im Nachhinein anpassen)

Zu deinem eigentlichen Problem:

Du setzt den DataContext deiner ComboBox im CodeBehind. "DataContext=kontakte" und sagst aber im XAML, dass "SelectedValue=IdKontakt" wäre. Jetzt überleg einmal: Kann deine IList<object> eine Property Names IdKontakte haben? Normalerweise nein.

Dieser Fehler wäre dir mit MVVM vermutlich nicht passiert, was aber nicht ausschließt, dass es nicht auch dort möglich ist.

Beheben kannst du das, indem du:

  • Quick&Dirty: Im PropertySetter von KontakteList nicht den DataContext setzt, sondern die ItemsSource.
  • oder: Per "{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.IdKontakte}" auf den DataContext des Fenster zurück verweist.

Lg, XXX

11.10.2012 - 16:48 Uhr

Mir fällt der Name von dem VS Tool gerade nicht ein - es ist glaub ich vorrangig um WCF Services zu testen aber funktioniert glaub ich auch mit normalen Webservices. Ist soweit ich weiß nur eine exe, die irgendwo liegt. Evt. erinnert sich wer anderer daran...

Lg, XXX

//Edit: Nachtrag bei mir liegts unter D:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\WcfTestClient.exe

11.10.2012 - 16:34 Uhr

Warum willst du denn sowas neu programmieren? Ich kenne nur ein Visual-Studio hauseigenes aber ich fand nach kurzem googeln einige weitere interessante Programme die genau das für dich erledigen. zB: wizdl

Lg, XXX

11.10.2012 - 11:51 Uhr

Hallo Beathoven,

diese Variante ist eine sehr gängige und bequeme aber mMn. keine sehr schöne, weil dadurch das Event immer für alle Commands abgesetzt wird die erzeugt wurden wodurch auch bei viel mehr als nötig dann die CanExecute Methode aufgerufen wird. Wenn der RelayCommand dann auch noch zusätzlich on-the-fly Auswertungen macht, kann das schon mal ordentlich unnötige Aufrufe kosten.

Hier ein Thread der sich ebenfalls mit dem Thema beschäftigt und ein Beispiel, das die Problematik zeigt: Frage zum RelayCommand.

Lg, XXX

11.10.2012 - 11:47 Uhr

Aus gegebenen Anlass in Command setzt Button nicht auf disabled, hab ich mir das Thema noch einmal genauer angesehen und bin eigentlich entsetzt wie falsch eine solche Implementierung eigentlich ist und doch verwendet sie allerwelt weil sie vermutlich bequem ist (auch ich selbst bis jetzt noch).

Hier ein Beispiel, dass die Problematik schön veranschaulicht wie ich finde:

<Window x:Class="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">
  <StackPanel>
    <TabControl ItemsSource="{Binding MyCommands}">
      
      <TabControl.ItemTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Key}"/>
        </DataTemplate>
      </TabControl.ItemTemplate>
      
      <TabControl.ContentTemplate>
        <DataTemplate>
          <ItemsControl ItemsSource="{Binding Value}">
            <ItemsControl.ItemTemplate>
              <DataTemplate>
                <Button Command="{Binding}" Content="{Binding Name}"/>
              </DataTemplate>
            </ItemsControl.ItemTemplate>
          </ItemsControl>
        </DataTemplate>
      </TabControl.ContentTemplate>
      
    </TabControl>
  </StackPanel>
</Window>

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Input;

public partial class MainWindow
{
    public Dictionary<string, ICommand[]> MyCommands { get; set; }

    public MainWindow()
    {
        InitializeComponent();

        MyCommands = new Dictionary<string, ICommand[]>();

        var commands = new ICommand[10];
        for (int j = 0; j < commands.Length; j++)
        {
            commands[j] = new MyCommandImpl();
        }
        MyCommands.Add("RequerySuggested", commands);

        var commands2 = new ICommand[10];
        for (int j = 0; j < commands2.Length; j++)
        {
            commands2[j] = new MyCommandImpl2();
        }
        MyCommands.Add("RaiseCanExecuteChanged", commands2);

        DataContext = this;
    }
}
public class MyCommandImpl : ICommand, INotifyPropertyChanged
{
    private int _clicked, _checked;
    private string _name;

    public string Name { get { return _name; } private set { _name = value; OnPropertyChanged("Name"); } }

    public void Execute(object parameter) { _clicked++; }

    public bool CanExecute(object parameter)
    {
        Name = ++_checked + " times checked";
        return _clicked < 3;
    }

    event EventHandler ICommand.CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
}
public class MyCommandImpl2 : ICommand, INotifyPropertyChanged
{
    private int _clicked, _checked;
    private string _name;

    public string Name { get { return _name; } private set { _name = value; OnPropertyChanged("Name"); } }

    public void Execute(object parameter) { _clicked++; RaiseCanExecuteChanged(null); }

    public bool CanExecute(object parameter)
    {
        Name = ++_checked + " times checked";
        return _clicked < 3;
    }

    public event EventHandler CanExecuteChanged;
    public void RaiseCanExecuteChanged(EventArgs e) { if (CanExecuteChanged != null) CanExecuteChanged(this, e); }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
}

//kurze Überlegung dazu: Hätte man in einer Applikation wie Mircosoft Word, die potentiell über 1000 Menüitems haben kann so eine Implementierung, die Applikation würde vermutlich nur damit beschäftigt sein deren CanExecute Status auszuwerten.

10.10.2012 - 14:50 Uhr

Hallo Himo,

ich habs selber noch nie probiert aber ich denke dieses Projekt sollte dir schon ein paar Möglichkeiten eröffnen: C# Midi Toolkit

Lg, XXX

10.10.2012 - 10:56 Uhr

Vielleicht hilft dir Methoden (C#) ja weiter.

Lg, XXX

10.10.2012 - 10:48 Uhr

...ich möchte ein event manuell, also per hand an bestimmter stelle auslösen. wie rufe ich dieses event auf? ...

offensichtlich nicht, sonst wäre dieser Post nicht entstanden.

Dein geposteter Codeausschnitt zeigt kein Event, sondern eine Methode, die an einem Event hängt.

private void DigitalIoControlStateChanged(object sender, EventArgs e)

Was willst du nun tun? Das Event aufrufen? Das geht nur von innerhalb der Klasse, die es besitzt, was auch sicherlich in meinem Link erklärt wird. Oder willst du nur die genannte Methode aufrufen? Wo ist das Problem?

Wie auch immer, gehört das zu den Grundlagen und sollte selbst erarbeitet werden.

Lg, XXX

10.10.2012 - 10:39 Uhr

Hallo Ivy,

bitte schau dir dazu die Grundlagen zu Events an.

Lg, XXX

09.10.2012 - 16:46 Uhr

Hallo Boris0815,

was du zu erreichen versuchst ist ein wenig wie die Katze beißt sich selbst in den Schwanz: Das Fenster soll sich der Größe der Controls anpassen und die Controls sollen sich an die Größe des Fensters anpassen. Beides gleichzeitig geht automatisch nicht (zumindest wars bei mir auch immer problematisch).

Aber eventuell reicht es ja wenn du die GridRow.Height der letzten Row auf * setzt. Das kann aber dann durchaus dazu führen, dass das Fenster sich nicht mehr automatisch verkleinert.

Lg, XXX

01.10.2012 - 11:49 Uhr

Hallo herbivore,

bis auf die von mir im Nachhinein hinzugefügte Bedingung mit den großen Anfangsbuchstaben vor Kleinbuchstaben erfüllt deine Lösung alle Kriterien und ist so nebenbei meistens um mindestens den Faktor 2 schneller als meine. 😃

Sehr gut gemacht - du bist nun also wieder dran die nächste Aufgabe zu stellen.

Lg, XXX

//Edit: Hier noch meine Lösung:

Zur Erklärung: In jedem Durchgang suche ich mit dem für jeden Match eigens übriggebliebenen RestPattern die Teiltreffer mit den längsten zusammenhängenden Zeichenfolgen raus und gehe mit denen in die nächste Runde um weiter zu suchen. Bevor ein Durchgang jedoch endet, werden die gefundenen Treffer mit der CompareTo Methode in "Match" nach ihrer Güte sortiert und es wird also immer mit den aktuell besten Treffern weitergesucht. Das wird solange durchgeführt, bis der aktuelle beste Treffer, kein RestPattern mehr übrig hat und somit die Suche beendet wurde.

Ich bin mir nicht sicher, ob meine Lösung garantiert immer die beste Variante findet aber zumindest tut sie es in meinen kleinen Testszenarios. Im Bezug auf den Aufwand, habe ich, wie vorhin erwähnt, keine so performante Lösung geschaffen wie Herbivore. In extremen Beispielen läuft mein Algorithmus ins Unendliche wodurch ich eine kleine Schummellösung eingebaut habe:
Wenn die zu durchsuchenden TeilMatches einen Wert überschreiten(hier matchesCount>50000) dann soll nach einem sehr einfachen Prinzip first-match->result gesucht werden. Diese einfache Methode "FindQuickMatch" sucht demnach klarerweise nicht nach allen Regeln aber das nehme ich hier in Kauf. Es wird ja trotzdem ein Match gefunden, nur eben nicht der idealste. 😃


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;

    public static class TextSearch
    {
        private class MatchPattern : IComparable<MatchPattern>
        {
            internal Match Match { get; private set; }
            internal string PatternRest { get; private set; }

            public MatchPattern(Match match, string patternRest)
            {
                Match = match;
                PatternRest = patternRest;
            }

            public int CompareTo(MatchPattern other)
            {
                return Match.CompareTo(other.Match);
            }
        }

        public static Match FindMatch(string input, string pattern)
        {
            if (input == null || pattern == null)
                return new Match();

            var wordStarts = new bool[input.Length];
            var startCapitals = new bool[input.Length];

            for (int i = 0; i < input.Length; i++)
            {
                if (i == 0 || (char.IsLetter(input[i]) && (!char.IsLetter(input[i - 1]) || char.IsUpper(input[i]) && char.IsLower(input[i - 1]))))
                {
                    wordStarts[i] = true;
                    startCapitals[i] = char.IsUpper(input[i]);
                }
            }

            return FindMatch(input.ToLower(), Regex.Replace(pattern, @"\s+", "").ToLower(), wordStarts, startCapitals);
        }

        private static Match FindMatch(string input, string pattern, bool[] wordStarts, bool[] startCapitals)
        {
            var matches = new List<MatchPattern> { new MatchPattern(new Match(), pattern) };

            int matchesCount = 0;
            do
            {
                MatchPattern match = matches[0];

                matches.Remove(match);

                IEnumerable<MatchPattern> newMatches = input.FindIndices(match.PatternRest[0], match.Match.RightIndex)
                    .Select(i => CreateMatch(match.Match, input, i, match.PatternRest, wordStarts, startCapitals));

                matches.AddRange(newMatches);

                if (matches.Count == 0)
                    return new Match();

                if ((matchesCount += matches.Count) > 50000)
                    return FindQuickMatch(input, pattern);

                var maxLength = matches.Select(m => m.Match.TotalLength)
                    .OrderByDescending(length => length)
                    .Take(2)
                    .OrderBy(length => length)
                    .FirstOrDefault();

                matches.RemoveAll(mp => mp.Match.TotalLength < maxLength);
                matches.Sort();

            } while (matches[0].PatternRest.Length > 0);

            return matches[0].Match;
        }

        private static Match FindQuickMatch(string input, string pattern)
        {
            var match = new Match();

            for (int i = 0, offset = 0, lastOffset = -1; i < pattern.Length; i++, lastOffset = ++offset)
            {
                if ((offset = input.IndexOf(pattern[i], offset)) < 0)
                    return new Match();

                if (lastOffset == offset)
                {
                    var oldPart = match[match.Count - 1];
                    match.Remove(oldPart);
                    match.Add(new MatchPart(oldPart.Index, oldPart.Length + 1));
                }
                else match.Add(new MatchPart(offset, 1));
            }
            return match;
        }


        private static MatchPattern CreateMatch(IEnumerable<MatchPart> parts, string input, int i, string pattern, bool[] wordStarts, bool[] startCapitals)
        {
            int length = GetLength(input.Substring(i), pattern);

            var match = new Match(parts)
            {
                new MatchPart(i, length, wordStarts[i], startCapitals[i])
            };

            return new MatchPattern(match, pattern.Substring(length));
        }

        private static int GetLength(string input, string pattern)
        {
            int length = 0;

            for (int p = 0; p < input.Length && p < pattern.Length && input[p] == pattern[p]; p++)
                length++;

            return length;
        }

        private static IEnumerable<int> FindIndices(this string text, char c, int indexFrom = 0)
        {
            while ((indexFrom = text.IndexOf(c, indexFrom)) >= 0)
                yield return indexFrom++;
        }
    }

Match wurde bei mir auch viel mehr erweitert, weil sich hier die ganze Bewertung eines Matches abspielt. Hier kann man im Gegensatz zu Herbivores Lösung sehr flexibel an den Bedingungen schrauben ohne den eigentlichen Algorithmus anpassen zu müssen.(Was ich ja durch Pperformanceeinbußen in Kauf nehme)


    using System;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Collections.Generic;

    public class Match : ObservableCollection<MatchPart>, IComparable<Match>, IComparable
    {
        public Match() { }

        public Match(IEnumerable<MatchPart> match) : base(match.Select(part => new MatchPart(part))) { }



        public int RightIndex { get { return Count == 0 ? 0 : this[Count - 1].Right; } }

        public int TotalLength { get; private set; }

        private double _averageLength;
        private int _boundaries;
        private int _capitalLetters;
        private int _distance;
        private double _index;

        private bool _partsChanged;

        protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            _partsChanged = true;

            TotalLength = (Count == 0) ? 0 : this.Sum(p => p.Length);

            base.OnCollectionChanged(e);
        }



        public int CompareTo(object obj)
        {
            return CompareTo(obj as Match);
        }

        public int CompareTo(Match other)
        {
            return Compare(this, other);
        }

        private static int Compare(Match x, Match y)
        {
            if (x.Count == 0 && y.Count > 0)
                return -1;
            if (x.Count > 0 && y.Count == 0)
                return 1;

            if (x._partsChanged)
                x.CalculateComparisonValues();
            if (y._partsChanged)
                y.CalculateComparisonValues();

            int averageLenght = x._averageLength.CompareTo(y._averageLength);
            if (averageLenght != 0)
                return -averageLenght;

            int boundaries = x._boundaries.CompareTo(y._boundaries);
            if (boundaries != 0)
                return -boundaries;

            int capitalLetters = x._capitalLetters.CompareTo(y._capitalLetters);
            if (capitalLetters != 0)
                return -capitalLetters;

            int distance = x._distance.CompareTo(y._distance);
            if (distance != 0)
                return distance;

            int index = x._index.CompareTo(y._index);
            if (index != 0)
                return index;

            return 0;
        }

        private void CalculateComparisonValues()
        {
            _partsChanged = false;

            _index = 0;
            _averageLength = 0;
            _boundaries = 0;
            _capitalLetters = 0;
            _distance = 0;

            if (Count > 0)
            {
                foreach (MatchPart part in Items)
                {
                    _index += part.Index;
                    if (part.IsWordStart)
                        _boundaries++;
                    if (part.IsStartLetterCapital)
                        _capitalLetters++;
                }

                _index /= Count;
                _averageLength += TotalLength / (double)Count;

                _distance = this[Count - 1].Index - this[0].Index;
            }
        }
    }


    public struct MatchPart
    {
        public MatchPart(MatchPart other)
            : this(other.Index, other.Length, other.IsWordStart, other.IsStartLetterCapital) { }

        public MatchPart(int index, int length) : this(index, length, false, false) { }

        public MatchPart(int index, int length, bool isWordStart, bool isStartLetterCapital)
            : this()
        {
            Index = index;
            Length = length;
            IsWordStart = isWordStart;
            IsStartLetterCapital = isStartLetterCapital;
        }


        public int Index { get; private set; }
        public int Length { get; private set; }
        public int Right { get { return Index + Length; } }

        public bool IsWordStart { get; private set; }
        public bool IsStartLetterCapital { get; private set; }
    }

//Edit²: Die 50 Zeilen Grenze für Aufgaben hier hatte ich erst nachdem ich diese gestellt hatte gelesen^^

27.09.2012 - 16:24 Uhr

Hallo TheBrainiac und wer sonst noch mitliest,

ich habe vermutlich noch viel weniger Weberfahrung als der Threadstarter und muss mir aktuell überlegen wie am besten eine Webseite umzusetzen wäre.

Nachdem ich auch noch nie mit einem CMS gearbeitet haben kann ich auch nicht entscheiden ob sowas für mich das richtige ist.

Umzusetzen müsste ich also eine Webseite, in die Gebäudespezifische Daten eingefügt werden um dann wiederum Reports über diese Daten generieren zu können und auszugeben. Das ganze muss keine Graphisch aufwendige Lösung sein.

  • Die Daten sind vorraussichtlich dynamisch hinterlegt und die Attributstrukturen können sich im Laufe der Zeit verändern. Dabei sollte sich die Webseite entsprechend automatisch anpassen können.

Ich habe schon einmal in einem ASP.NET Projekt mitgearbeitet aber ich hab leider keinerlei Erfahrung worum es geht wenn man eines von Grund auf neu erstellen muss.

Ich hab nun ein wenig recherchiert und mir auch Frameworks wie DotNetNuke angesehen aber ohne sie verwendet zu haben kann ich auch nur schwer eine Aussage darüber treffen ob es das geeignete ist.

Meine Frage nun - kann man mit einem CMS wie DNN eine Web-Anwendung erstellen wie ich sie beschrieben habe oder welche alternativen habe ich (außer von Scratch wegzuprogrammieren). Am liebsten würde ich so wenig wie möglich mit dem Frontend zu tun haben außer....

... nachdem ich mich in WPF relativ wohl fühle, ist es (noch) sinnvoll eine Web-Applikation in Silverlight umzusetzen? Irgendwo glaub ich einmal gelesen zu haben, dass SL nicht mehr weitergeführt wird? Solange es aber existiert könnte mir das doch egal sein oder?

Über Meinungen und Anregungen würd ich mich sehr freuen!

Lg, XXX

25.09.2012 - 10:44 Uhr

Hallo zusammen,

ich kann dazu nur sagen, dass meine ursprüngliche Implementierung eine sehr naive war und ich auch nur in relativ kurzen Texten relativ eindeutige Textpassagen suchen lasse wodurch der Aufwand nie ein Problem war. Nachdem mir herbivore aber nun die Schwierigkeiten aufgezeigt hat, bin ich nun selbst auch wieder am Werken um eine optimalere Lösung zu finden.

Lg, XXX

20.09.2012 - 16:22 Uhr

Vielen Dank für deine Lösung - ich hab die Aufgabe offenbar anfänglich zu einfach eingeschätzt. 😃

Meine Aufgabe ist nun nicht sonderlich ausgefallen, weil es sich ebenfalls um eine Textsuche handelt aber sie ist dennoch interessant wie ich finde:

Ausgehend vom ReSharper der meiner Meinung nach eine unglaublich tolle File-, Member- und IntelliSense- Suche hat, habe ich einmal für ein Projekt versucht ähnliches Suchverhalten umzusetzen und bin von dem Resultat sehr begeistert. Algorithmisch ists zwar nur eine Textsuche kann aber trotzdem recht knifflig sein:

Das ist die Testumgebung:


        static void Main(string[] args)
        {
            /*
             * Ein Match ist dann erfolgreich, wenn alle Zeichen aus dem Pattern im Input gefunden wurden.
             *  - falls der Match nicht klappt - wird ein leerer Match zurückgegeben -> eben kein Match
             * Dabei werden groß/klein-Schreibung sowie Whitespaces im Pattern ignoriert.
             * Ein leerer Pattern ist automatisch ein leerer Match.
             * Das Pattern kann potentiell in mehreren Varianten passen aber nur die "Beste" soll zurückgegeben werden.
             * Dabei sollen die Teilergebnisse gewichtet werden:
             *  - Matches mit weniger Parts werden anderen mit mehreren bevorzugt
             *  - Bei gleicher Partanzahl, gewinnt der Match der mehr Anfangsbuchstaben in den Parts hält
             *     -> Als Anfangsbuchstaben werden alle Großbuchstaben nach einem Kleinbuchstaben und alle Buchstaben, vor denen kein Buchstabe steht, gewertet. "Hallo Welt", "HalloWelt" - beide Varianten haben zwei Wortanfänge
             *  - Beim Auswerten der Anfangsbuchstaben sollen Großbuchstaben den Kleinbuchstaben bevorzugt werden
             *  - Bei gleicher Partanzahl und gleicher Anfangsbuchstabenanzahl, gewinnt der Match bei dem die Parts weiter am Anfang stehen.
             */

            TestAndPrintMatch("Das ist ein Auto", "aa", "D[a]s ist ein [A]uto");

            TestAndPrintMatch("Hallo Welt", "Hallo Welt", "[Hallo] [Welt]");

            TestAndPrintMatch("Hawai hat schöne Wellen", "hw", "[H]awai hat schöne [W]ellen");

            TestAndPrintMatch("Hallo Welt", "hw", "[H]allo [W]elt");

            TestAndPrintMatch("H a l l o Hallo", "halo", "H a l l o [Hal]l[o]");

            TestAndPrintMatch("DasIstIrgendEinText", "irgend", "DasIst[Irgend]EinText");

            TestAndPrintMatch("Jetzt ists aus mit der Maus", "aus", "Jetzt ists [aus] mit der Maus");

            TestAndPrintMatch("Das ist mein Auto", "a u t o", "Das ist mein [Auto]");

            TestAndPrintMatch("Das ist mein Auto", "ma", "Das ist [m]ein [A]uto");

            TestAndPrintMatch("Ohne Treffer", "xx", "Ohne Treffer");

            TestAndPrintMatch("Hier steht mein Haus", "iHaus", "H[i]er steht mein [Haus]");

            TestAndPrintMatch("Peter Müller träumte von Peter Pan", "Peter Pan", "[Peter] Müller träumte von Peter [Pan]");

            TestAndPrintMatch(new String('a', 200), new String('a', 100), "");

            Match match1 = TextSearch.FindMatch("Anna und Toni können sich zusammenraufen", "autokauf");
            Match match3 = TextSearch.FindMatch("Ich habe mir kein Auto gekauft", "autokauf");
            Match match2 = TextSearch.FindMatch("Autos kauft man nicht im Supermarkt", "autokauf");

            List<Match> matches = new List<Match> { match1, match2, match3 };

            matches.Sort();

            Console.WriteLine(matches[0] == match2);
            Console.WriteLine(matches[1] == match3);
            Console.WriteLine(matches[2] == match1);
        }

        private static void TestAndPrintMatch(string input, string pattern, string expected)
        {
            Match match = TextSearch.FindMatch(input, pattern);

            int offset = 0;
            foreach (MatchPart part in match)
            {
                input = input.Insert(part.Index + offset++, "[");
                input = input.Insert(part.Index + offset++ + part.Length, "]");
            }

            PrintText("Soll: ", expected);
            PrintText("Ist : ", input);

            Console.WriteLine();
        }

        private static void PrintText(string preText, string expected)
        {
            ConsoleColor defaultColor = Console.ForegroundColor;

            Console.Write(preText);

            foreach (char c in expected)
            {
                Console.ForegroundColor = (c == '[' || c == ']') ? ConsoleColor.Red : defaultColor;
                Console.Write(c);
            }
            Console.ForegroundColor = defaultColor;
            Console.WriteLine();
        }

und hier soll die Implementierung rein:


        public class TextSearch
        {
            public static Match FindMatch(string input, string pattern)
            {
                //implement this method
            }
        }

        public class Match : Collection<MatchPart>, IComparable<Match>, IComparable
        {
            public int CompareTo(Match other)
            {
                //and this method
            }

            public int CompareTo(object obj)
            {
                return CompareTo(obj as Match);
            }
        }

        public struct MatchPart
        {
            public int Index { get; set; }
            public int Length { get; set; }
        }

Zu implementieren ist die Methode FindMatch. Bei Bedarf kann auch die Klasse Match bzw. MatchPart angepasst werden.

Lg und viel Vergnügen,

XXX

//Edit: Match angepasst - die CompareTo Methode wird fürs Sortieren gebraucht um später mehrere Treffer nach besten Treffern sortieren zu können.

//Edit²: Main Methode angepasst um noch einen weiteren Testfall(Sortierung) sowie die Vorgaben etwas mehr fixiert: ~~Bei gleicher durchschnittlicher Textlänge und gleicher Anfangs und Endbuchstabenanzahl gewinnt das Ergebnis bei denen die Teiltreffer weiter links angeordnet sind.~~Bei gleicher Partanzahl und gleicher Anfangsbuchstabenanzahl, gewinnt der Match bei dem die Parts weiter am Anfang stehen.

//Edit³: Bedingungen leicht umformuliert und angepasst: Wortenden werden jetzt nicht sonderlich bewertet

//Edit die 4.: Bedingungen nochmals erweitert - Beim Finden von Anfangsbuchstaben werden Großbuchstaben den Kleinbuchstaben bevorzugt behandelt.

20.09.2012 - 16:13 Uhr

Zum (nicht)statischen nochwas: Es kann ja gewünscht sein, dass man evt. zwei unterschiedliche Scriptmanager laufen lässt, welche von einander nichts wissen sollen.

Und um Scripts zu identifizieren bietet sich ebenfalls Objektorientierung an:


ScriptManager manager = new ScriptManager();
IScript script = manager.Create(meinScriptString);

//ab hier kann ich mein Script ja schon selbstständig weiter ausführen oder nicht? 
script.Main(/*mit meinen Args*/);

//oder alternativ halt
manager.Run(script, args);

Auch im Bezug auf Fehlerauswertung fände ich es unpraktisch, wenn ich den ScriptManager an mehreren Orten verwenden wollen würde und dann dort Fehler drinnen sind, die mit meiner (lokalen) Ausführung garnichts zu tun haben.

just my 2 cents...

Lg, XXX

20.09.2012 - 14:58 Uhr

Hallo Ayra,

ich finde die Idee toll nur funktionierts bei mir noch nicht richtig - Wie kann ich zum Beispiel die PresentationFramework.dll einbinden? Egal was ich versuche, er meint er findet sie nicht.

Und das der ScriptManager statisch ist gefällt mir nicht so - Lieber wäre mir, ich könnte den Manager instantiieren und mit dem Objekt weiterarbeiten.

Lg, XXX

/Edit: Und die Klassen sollten unter einem Namespace liegen um die Klassen evt. von bestehenden Klassen unterscheiden zu können.

19.09.2012 - 13:06 Uhr

Wenn ich so einen Fall vermute, setze ich einen BreakPoint im Setter und Getter des Properties und schau mir mit this.GetHashCode() an ob bei jedem Aufruf das selbe Objekt aufgerufen wird oder ob es doch mehrere Instanzen gibt.

Lg, XXX

19.09.2012 - 13:02 Uhr

Pff das war jetzt aber eine schwere Geburt - hätte vorher nicht so vorlaut sein sollen von wegen soo einfach^^

Hier nun die (hoffentlich) endgültige und etwas leserlich aufbereitete Version:


        private static bool FullMatch(string input, string pattern)
        {
            input = "" + input;
            pattern = "" + pattern;

            string oldPattern = pattern;
            while ((pattern = pattern.Replace("**", "*")) != oldPattern)
                oldPattern = pattern;

            return FullMatch(input, pattern, 0, 0);
        }

        private static bool FullMatch(string input, string pattern, int iInput, int iPattern)
        {
            for (; iPattern < pattern.Length; iPattern++, iInput++)
            {
                if (pattern[iPattern] == '*')
                {
                    iPattern++;

                    do
                    {
                        if (pattern.Length == iPattern)
                            iInput = input.Length;
                        else
                        {
                            char nextCharacter = (iInput < input.Length && pattern[iPattern] == '?')
                                                     ? input[iInput]
                                                     : pattern[iPattern];

                            iInput = input.IndexOf(nextCharacter, iInput);

                            if (iInput < 0) return false;
                        }

                        if (FullMatch(input, pattern, iInput, iPattern))
                            return true;

                        iInput++;

                    } while (true);
                }

                if (iInput == input.Length || iInput < input.Length && pattern[iPattern] != '?' && pattern[iPattern] != input[iInput])
                    return false;
            }
            return input.Length == iInput;
        }

Lg, XXX

PS: Du bist sicherlich nicht zu pingelig sondern ich zu nachlässig - aber mit Try&Error bin ich noch immer sehr gut vorangekommen^^

19.09.2012 - 12:40 Uhr

Zeig mal her wie und wo du den DataContext setzt: Ich vermute, dass es zwei oder mehrere Instanzen von UserControl1 gibt und du aber die Daten(das Property) auf einer falschen Instanz manipulierst.

Das Problem liegt vermutlich daran, dass Controls bei einem Load erzeugt und bei einem Unload zerstört werden. Wenn du also später auf einer alten Instanz das Property veränderst bemerkt die neue Instanz davon natürlich nichts, weil die ja wieder ihr eigener DataContext ist. Dieser Fall trifft speziell dann auf, wenn das UserControl in einem Item- oder Tab-Control als Item liegt.

Auch aus diesem Grund sollte man auf MVVM setzen.

Lg, XXX

19.09.2012 - 12:23 Uhr

Pfff bist du aber genau 😛

Hier also eine erneut überarbeitete Version:^^


        private static bool FullMatch(string input, string pattern)
        {
            if(input==null || pattern==null)
                return false;

            string oldPattern = pattern;
            while ((pattern = pattern.Replace("**", "*")) != oldPattern)
                oldPattern = pattern;

            return FullMatch(input, pattern, 0, 0);
        }

        private static bool FullMatch(string input, string pattern, int i, int j)
        {
            if (j < 0)
                return false;

            for (; i < pattern.Length; i++, j++)
            {
                if (pattern[i] == '*')
                {
                    i++;

                    while ((j = pattern.Length == i ? input.Length : input.IndexOf(pattern[i], j)) >= 0)
                    {
                        if (FullMatch(input, pattern, i, j++))
                            return true;
                    }
                }

                if (j < 0 || input.Length == j || pattern[i] != '?' && pattern[i] != input[j])
                    return pattern.Length == i;
            }
            return input.Length == j;
        }

19.09.2012 - 10:54 Uhr

So, nun nochmal eine iterative Lösung die den letzten Fall auch abdeckt:


        static void Main(string[] args)
        {
            Console.WriteLine(FullMatch("A", "A"));
            Console.WriteLine(!FullMatch("AB", "A"));
            Console.WriteLine(!FullMatch("A", "a"));
            Console.WriteLine(FullMatch("HALLO", "HALLO"));
            Console.WriteLine(FullMatch("HALLO", "HA**O"));
            Console.WriteLine(FullMatch("HALLO", "HA************O"));
            Console.WriteLine(FullMatch("HALLO", "HA*"));

            Console.WriteLine(FullMatch("A", "?"));
            Console.WriteLine(FullMatch("B", "?"));
            Console.WriteLine(FullMatch("?", "?"));
            Console.WriteLine(FullMatch("*", "?"));// (im Text haben die Platzhalterzeichen keine Sonderbedeutung)
            Console.WriteLine(!FullMatch("den leeren String", "?"));
            Console.WriteLine(!FullMatch("AB", "?"));
            Console.WriteLine(!FullMatch("A", "??"));
            Console.WriteLine(FullMatch("AA", "??"));
            Console.WriteLine(FullMatch("AB", "??"));
            Console.WriteLine(!FullMatch("ABC", "??"));
            Console.WriteLine(FullMatch("ABC", "??C"));
            Console.WriteLine(FullMatch("CCC", "??C"));
            Console.WriteLine(FullMatch("CC*C", "??*C"));
            Console.WriteLine(!FullMatch("CCCC", "??C"));
            Console.WriteLine(!FullMatch("ABD", "??C"));
            Console.WriteLine(!FullMatch("AC", "??C"));
            Console.WriteLine(FullMatch("", "*"));
            Console.WriteLine(!FullMatch("*", ""));
        }

        private static bool FullMatch(string input, string pattern)
        {
            string oldPattern = pattern;
            while ((pattern = pattern.Replace("**", "*")) != oldPattern)
                oldPattern = pattern;

            int j = 0;
            for (int i = 0; i < pattern.Length; i++, j++)
            {
                if (pattern[i] == '*')
                    j = pattern.Length == ++i ? input.Length : input.IndexOf(pattern[i], j);
                
                if (input.Length == j || pattern[i] != '?' && pattern[i] != input[j])
                    return pattern.Length == i;
            }
            return input.Length == j;
        }

Lg, XXX

18.09.2012 - 14:39 Uhr

Wenn du an das Property ZAngle Binden willst musst du entweder das Control selbst als DataContext setzen: ZB im Konstruktor DataContext=this; oder du suchst das Control via RelativeSource

{Binding RelativeSource={RelativeSource {x:Type UserControl1}}, Path=ZAngle}

(Wobei ich hier nicht weiß ob UserControl1 oder nur UserControl als Typ angegeben werden muss.

Lg, XXX

18.09.2012 - 14:25 Uhr

Eine ähnliche Aufgabe hab ich mir auch überlegt aber ich dachte mir sie wäre zu aufwendig - kommt dafür als nächstes. 😃


        static void Main(string[] args)
        {
            Console.WriteLine(FullMatch("A", "A"));
            Console.WriteLine(!FullMatch("AB", "A"));
            Console.WriteLine(!FullMatch("A", "a"));
            Console.WriteLine(FullMatch("HALLO", "HALLO"));
            Console.WriteLine(FullMatch("HALLO", "HA**O"));
            Console.WriteLine(FullMatch("HALLO", "HA*"));

            Console.WriteLine(FullMatch("A", "?"));
            Console.WriteLine(FullMatch("B", "?"));
            Console.WriteLine(FullMatch("?", "?"));
            Console.WriteLine(FullMatch("*", "?"));// (im Text haben die Platzhalterzeichen keine Sonderbedeutung)
            Console.WriteLine(!FullMatch("den leeren String", "?"));
            Console.WriteLine(!FullMatch("AB", "?"));
            Console.WriteLine(!FullMatch("A", "??"));
            Console.WriteLine(FullMatch("AA", "??"));
            Console.WriteLine(FullMatch("AB", "??"));
            Console.WriteLine(!FullMatch("ABC", "??"));
            Console.WriteLine(FullMatch("ABC", "??C"));
            Console.WriteLine(FullMatch("CCC", "??C"));
            Console.WriteLine(FullMatch("CC*C", "??*C"));
            Console.WriteLine(!FullMatch("CCCC", "??C"));
            Console.WriteLine(!FullMatch("ABD", "??C"));
            Console.WriteLine(!FullMatch("AC", "??C"));
        }

        private static bool FullMatch(string input, string pattern)
        {
            return FullMatchInternal(input, pattern, false);
        }

        private static bool FullMatchInternal(string input, string pattern, bool findAny)
        {
            if (input.Length == 0 && pattern.Length == 0)
                return true;

            if (input.Length == 0)
                return false;

            if (findAny)
            {
                if (pattern.Length == 0)
                    return true;

                return FullMatchInternal(input.Substring(1), pattern, input.Substring(1)[0] != pattern[0]);
            }

            if (pattern.Length == 0)
                return false;

            if (pattern[0] == '?')
                return FullMatch(input.Substring(1), pattern.Substring(1));

            if (pattern[0] == '*')
                return FullMatchInternal(input, pattern.Substring(1), pattern.Substring(1).Length == 0 || pattern.Substring(1)[0] != '*');

            if (pattern[0] == input[0])
                return FullMatch(input.Substring(1), pattern.Substring(1));

            return false;
        }

18.09.2012 - 10:44 Uhr

Dann würd ich vermuten, dass man ganz einfach einen eigenen Appender schreiben kann, der dann genau das tut was du willst. Hier ein Beispiel: Creating a custom log4net appender

Lg, XXX

18.09.2012 - 09:59 Uhr

Ich habe gerade keine Idee - kann also posten wer will.

18.09.2012 - 09:24 Uhr

Warum verwendest du nicht den SMTPAppender? Der verschickt die Mails vollautomatisch.

Lg, XXX

17.09.2012 - 18:33 Uhr

Jap, da hab ich wohl zu schleißig getestet. 😛 Habs im vorigen Post ausgebessert - Beim Characterparsen hat was nicht hingehaun.

Lg, XXX

17.09.2012 - 17:40 Uhr

        static void Main(string[] args)
        {
            BerecheneKleinsteZugfolge("G1", "A7").ForEach(item => Console.WriteLine(item));
            Console.ReadLine();
        }

        private static List<string> BerecheneKleinsteZugfolge(string start, string ziel)
        {
            int minCount = -1;

            List<string> kleinsteZugfolge = BerechneAlleZugfolgen(start, ziel, new Stack<string>(), ref minCount)
                .OrderBy(list => list.Count)
                .FirstOrDefault();

            return kleinsteZugfolge.ToList();
        }

        private static IEnumerable<List<string>> BerechneAlleZugfolgen(string start, string ziel, Stack<string> previous, ref int minCount)
        {
            var result = new List<List<string>>();

            if (start == null || previous.Contains(start) || (minCount > 0 && minCount == previous.Count))
                return result;

            if (start == ziel)
            {
                result.Add(new List<string>(previous.Reverse()) { ziel });
                minCount = previous.Count;

                return result;
            }

            previous.Push(start);

            result.AddRange(BerechneAlleZugfolgen(MoveTo(start, 2, -1), ziel, previous, ref minCount));
            result.AddRange(BerechneAlleZugfolgen(MoveTo(start, 2, 1), ziel, previous, ref minCount));

            result.AddRange(BerechneAlleZugfolgen(MoveTo(start, -2, -1), ziel, previous, ref minCount));
            result.AddRange(BerechneAlleZugfolgen(MoveTo(start, -2, 1), ziel, previous, ref minCount));

            result.AddRange(BerechneAlleZugfolgen(MoveTo(start, 1, -2), ziel, previous, ref minCount));
            result.AddRange(BerechneAlleZugfolgen(MoveTo(start, 1, 2), ziel, previous, ref minCount));

            result.AddRange(BerechneAlleZugfolgen(MoveTo(start, -1, -2), ziel, previous, ref minCount));
            result.AddRange(BerechneAlleZugfolgen(MoveTo(start, -1, 2), ziel, previous, ref minCount));

            previous.Pop();

            return result;
        }

        private static string MoveTo(string position, int deltaX, int deltaY)
        {
            int x = position[0] - (65 + 1) + deltaX;
            int y = position[1] - 48 + deltaY;

            if (x < 1 || x > 8 || y < 1 || y > 8)
                return null;

            char xChar = (char)(x + (65 - 1));
            char yChar = (char)(y + 48);
            
            return "" + xChar + yChar;
        }

A1
C2
D4
E6
F8

Bzgl. weiterer Aufgabe hab ich zurzeit keine Idee - kann also posten wer will.

13.09.2012 - 16:09 Uhr

Wie wärs wenn du einmal in deinen Code debuggst und den Wert in deiner Variable "zeichen" anschaust?

13.09.2012 - 10:14 Uhr

Ich denke so müsste es funktionieren:


Maximum="{Binding Source={x:Static Forms:SystemInformation.PrimaryMonitorSize}, Path=Width}"

Lg, XXX

11.09.2012 - 16:51 Uhr

Anstatt eines zweidimensionalen Arrays kannst du dir ja auch ein Array von einem Array halten und diese Array Elemente kannst du dann übergeben:


double[][] data...;

...AddData(data[i]) //so ungefähr.


Man darf dabei aber nicht vergessen dass durch übergabe des ganzen Arrays nur die Referenz auf jenes übergeben wird. D.h. wenn dieses sich später noch verändert, verändert es sich überall wo es übergeben wurde.

Lg, XXX