Laden...

Forenbeiträge von ByteDevil Ingesamt 132 Beiträge

27.09.2019 - 11:07 Uhr

Das ist eine gegensätzliche Anforderung. Kann so nicht funktionieren.

Wie meinst du das? Das ist doch als würde ich dich bitten mir aus lauter Koffern den zu geben, auf dem mein Name drauf steht. Dafür musst du wissen was ein Koffer ist, das ein Name darauf stehen kann und als Query teile ich dir meinen Namen mit. Du gibst mir den Koffer ohne zu wissen was darin ist und ob da überhaupt was drin ist. Wieso ist das so abwegig?

Du kannst natürlich nur die Elemente gegen die Datenbank abfragen, die im Query mitkommen - aber nur die werden dann eben auch geladen; nicht alle.

Genau das ist mein Problem...bei der Deserialisierung muss ich ja den richtigen Typ kennen. Gebe ich im obigen Beispiel PersonFlat an, wird nur deserialisiert was PeronFlat kennt. Der Rest wird verworfen. Document DB speichert doch auch alles als JSON, oder? Kann ich nicht einfach nur irgendwie den json string bekommen? Oder ich mache eine Abfrage über PersonFlat und merke mir die ID's und hole mir dann jede Person über die ID...aber auch da brauche ich ja wieder eine Klasse zum deserialisieren...

27.09.2019 - 10:35 Uhr

verwendetes Datenbanksystem: CosmosDB

Hallo,

ich schreibe gerade eine REST-API die später dann in Azure laufen und den Inhalt einer CosmosDB als JSON zurückgeben soll. Die API kann bestimmte Filter in Form eines Query-Strings in der URL entgegen nehmen und formt daraus einen Linq-Ausdruck, der dann mittels des Microsoft.Azure.Documents.Client eine Datenbankabfrage macht. Jedes dieser Datenbankobjekte ist recht groß und die DB wird durch ein anderes Tool gefüttert, welches den Datentyp aus dem serialisiert wird immer genau kennt.
Nun kann es sein, dass sich die Struktur der Daten vielleicht einmal leicht ändern wird. Passiert das, möchte ich nicht jedes mal an den Webservice gehen und das DB model updaten, damit die neu hinzugekommenen Daten mit deserialisiert werden. Ich möchte das mein Webservice nur von den Properties weiß, nach denen mit einem Query-String gesucht werden können soll. Zurückgeben möchte ich aber immer alles von dem Objekt. So müsste ich dann nur was an dem Webservice ändern, wenn eine neue Filteroption her soll.
Ist das verständlich ausgedrückt?

EDIT: Nochmal ein kleines Beispiel:

class Person
    {
        public string Id { get; set; }
        public string Vorname { get; set; }
        public string Nachname { get; set; }
        public string Adresse { get; set; }
        public int Alter { get; set; }
        public bool Geschlecht { get; set; }
    }

Tool A definiert diese Struktur und füttert die DB auch direkt.

Tool B weiß nur das da:

class PersonFlat
    {
        public string Id { get; set; }
        public string Vorname { get; set; }
        public int Alter { get; set; }
        public bool Geschlecht { get; set; }
    }

Und das auch nur, weil Tool B die Datenbankabfrage nach Id, Vorname, Alter und Geschlecht machen können soll. Dennoch soll Tool B dann trotzdem ALLES als JSON aussprucken können. Geht das?

18.09.2019 - 08:18 Uhr

Nimm einen ProgressBar und färbe ihn entsprechend ein.

Edit: Ups - falsches Forum. Dachte WPF

17.09.2019 - 15:30 Uhr

In the category of the pot talking to the pan, I present you ScrollViewer. It's the main control to implement scrolling in your templates, but it's also the one not respecting a very fundamental rule of scrolling: if you're done scrolling, let your parent scroll!

Not only does ScrollViewer handles the mouse scrolling even when no more scrolling is needed, but it also does so when there's nothing to scroll, or worse when it is told not to scroll!

Das scheint ein komplizierteres Problem zu sein. Habe hier was dazu gefunden, allerdings klappt das nur, solange in den ScrollViewern nur controls sind die von UIElement erben. Habe bei mir noch irgendwo anscheinend einen Document.Run drin, dabei crashed es dann. Verhindere ich das mit einer prüfung auf null, funktioniert es manchmal und manchmal nicht...

Bin sehr verzweifelt...

17.09.2019 - 09:27 Uhr

Habe mir jetzt selbst ein UserControl geschrieben das macht was ich möchte. Hier ist es, falls ich jemandem damit eine Freude machen kann:


public class TrailerPanel : UserControl
{
    readonly Grid mainGrid = new Grid();
    readonly ScrollViewer scrollViewer = new ScrollViewer();

    public FrameworkElement MainControl
    {
        get { return (FrameworkElement)GetValue(MainControlProperty); }
        set { SetValue(MainControlProperty, value); }
    }
    public static readonly DependencyProperty MainControlProperty =
        DependencyProperty.Register("MainControl", typeof(FrameworkElement), typeof(TrailerPanel), new PropertyMetadata(null, MainControl_PropertyChanged));
    private static void MainControl_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) => (obj as TrailerPanel).scrollViewer.Content = (obj as TrailerPanel).MainControl;

    public FrameworkElement TrailingControl
    {
        get { return (FrameworkElement)GetValue(TrailingControlProperty); }
        set
        {
            if (TrailingControl != null)
                mainGrid.Children.Remove(TrailingControl);
            SetValue(TrailingControlProperty, value);
        }
    }
    public static readonly DependencyProperty TrailingControlProperty =
        DependencyProperty.Register("TrailingControl", typeof(FrameworkElement), typeof(TrailerPanel), new PropertyMetadata(null, TrailingControl_PropertyChanged));
    private static void TrailingControl_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        (obj as TrailerPanel).mainGrid.Children.Add((obj as TrailerPanel).TrailingControl);
        Grid.SetRow((obj as TrailerPanel).TrailingControl, 1);
    }

    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);

        Content = mainGrid;

        mainGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
        mainGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
            
        mainGrid.Children.Add(scrollViewer);
        Grid.SetRow(scrollViewer, 0);

        SizeChanged += BetterTrailerPanel_SizeChanged;
    }

    private void BetterTrailerPanel_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        mainGrid.RowDefinitions[0].MaxHeight = ActualHeight - mainGrid.RowDefinitions[1].ActualHeight;
        scrollViewer.MaxHeight = ActualHeight - mainGrid.RowDefinitions[1].ActualHeight;
    }
}

Verwendung:


<Grid>
    <controls:TrailerPanel>
        <controls:TrailerPanel.MainControl>
            <StackPanel>
                <Expander>
                    <Rectangle Width="100" Height="200"/>
                </Expander>
                <Expander>
                    <Rectangle Width="100" Height="200"/>
                </Expander>
                <Expander>
                    <Rectangle Width="100" Height="200"/>
                </Expander>
            </StackPanel>
        </controls:TrailerPanel.MainControl>
        <controls:TrailerPanel.TrailingControl>
            <Button Content="Button der immer sichtbar sein soll" Grid.Row="1" VerticalAlignment="Top"/>
        </controls:TrailerPanel.TrailingControl>
    </controls:TrailerPanel>
</Grid>

16.09.2019 - 16:42 Uhr

Evtl. hilft dir die Angabe von Height="Auto" und einer Angabe bei MaxHeight.

Aber was sollte ich sinnvolles bei MaxHeight angeben?

16.09.2019 - 16:36 Uhr

Jo, ich kenn das Problem leider nur zu gut von unseren eigenen Views - und dort konnten wir meistens durch umsortieren der Controls ein brauchbares UI erreichen.
Gibts einen Grund, warum der Button unten sein muss? Sonst würd ich den einfach mal nach oben verfrachten.

Leider ist das keine Option 😦 Handelt sich um eine Filter-UI wo ein Suchbutton unten sein soll. Würde eher verwirren wenn der Button über den ganzen Filtern ist.

16.09.2019 - 16:30 Uhr

Naja, das Problem ist eher, dass die RowDefinition deines StackPanel keine Height angegeben hat. Standardmäßig ist die \*, drum nimmt das Ding den ganzen Platz ein, den der Button nicht braucht.
Damit wird der Button auch immer unten dran kleben.

Richtig, eine feste Höhe kann ich aber nicht definieren, weil ich das Fenster ja größer oder kleiner machen können möchte. Auf Auto kann ich es auch nicht setzen, weil sonst der Button im nirgendwo verschwindet und das Grid einfach immer größer wird.

Edit: Es muss auch nicht zwingend diese Konstruktion mit dem StackPanel/Grid sein. Suche nur etwas das funktioniert^^

16.09.2019 - 16:21 Uhr

Ich würde mal darauf tippen, dass der Button ein
>
braucht.

Aber er ist alleine in einer Auto-Size GridRow? Oder wie meinst du das?

16.09.2019 - 16:04 Uhr

Hallo,

hat jemand eine Idee wie ich das schaffen könnte? Also ich habe eine vertikales Stackpanel mit mehreren Expandern darin. Dieses StackPanel steckt in einem ScrollViewer. Unterhalb dessen ist ein Button den der User auf jeden Fall braucht.
Brauchen die Expander nun mehr Platz als da ist, erscheint eine vertikale Scrollbar. Der Button bleibt auch sichtbar. Nun ist mein Problem, dass der Button IMMER ganz unten ist...also auch wenn mehr als genug Platz da ist. Ich hätte ihn aber immer gern direkt unter den Expandern...

Hier mal ein Minimalbeispiel:


<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <ScrollViewer Grid.Row="0">
        <StackPanel>
            <Expander>
                <Rectangle Width="100" Height="200"/>
            </Expander>
            <Expander>
                <Rectangle Width="100" Height="200"/>
            </Expander>
            <Expander>
                <Rectangle Width="100" Height="200"/>
            </Expander>
        </StackPanel>
    </ScrollViewer>
    <Button Content="Button der immer sichtbar sein soll" Grid.Row="1" VerticalAlignment="Top"/>
</Grid>

12.09.2019 - 09:59 Uhr

Hi,

ich habe zwei ineinander verschachtelte ScrollViewer. Wenn ich mit der Maus über dem inneren bin, scrolle ich den vertikal hoch und runter mit dem Mausrad...alles gut. Bin ich ausserhalb, aber immer noch im äußeren, scrolle ich den äusseren. Auch alles prima so. Bin ich nun aber im inneren und habe beispielsweise nach ganz oben gescrollt, wäre es schön wenn der äussere dann das Scroll-Event kriegt und dann nach oben Scrollt. Analog natürlich auch abwärts. Dachte irgendwie das wäre das Standardverhalten von WPF aber anscheinend habe ich mich getäuscht. Gibt es einen einfachen Weg das zu erreichen?

Grüße

EDIT: In diesem Post ist ein gif zu sehen in dem das gezeigt ist was ich will. Auch wenn das dort als Bug bezeichnet wird.

EDIT: Minimalbeispiel:

<ScrollViewer VerticalScrollBarVisibility="Auto">
            <Grid Width="400" Height="600">
                <ScrollViewer>
                    <StackPanel Width="200">
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                        <TextBlock Text="1234"/>
                    </StackPanel>
                </ScrollViewer>
            </Grid>
        </ScrollViewer>
06.08.2019 - 16:25 Uhr

Bin mir nicht sicher ob ich dich richtig verstehe. Also ist das Kernproblem eine For-Schleife laufen zu lassen, die du pausieren können möchtest ohne das der UI-Thread blockiert wird? Du könntest die Schleife in einem neuen Thread ausführen und den bei Bedarf mit Thread.Sleep() pausieren.

05.08.2019 - 09:20 Uhr

Ich bin etwas verwirrt. Dein "NameToBrushConverter" sollte doch einen Brush zurückgeben? Du gibst strings zurück.

return Brushes.LightGreen;

wäre da in der Tat richtig(er)

02.08.2019 - 10:51 Uhr

Hi,

ich habe ein Control entworfen, dass Bilder in Images in einer ListBox horizontal auflistet. Über dieser ListBox ist ein Image, welches immer eines der Bilder in groß anzeigt. Der User kann eines der Bilder in der ListBox anklicken, dann wird es in dem großen Image angezeigt. Eine TimeSpan gibt an, nach welcher Zeit automatisch das nächste Bild angezeigt wird. Da eventuell mehr Bilder in der ListBox sind, als nebeneinander angezeigt werden können, soll bei Bedarf eine horizontale ScrollBar erscheinen. Wird automatisch das nächste Bild angezeigt, welches ausserhalb des sichtbaren Bereiches ist, scrolle ich automatisch zu diesem Element.
Jetzt mein Problem: Hält der User die linke Maustaste auf dem Scrollbalken, will ich nicht automatisch scrollen. Nur wie detektiere ich das? Es ist mir gelungen eine Referenz auf den eingebauten ScrollViewer der ListBox zu kriegen. Doch weder der, noch die ListBox haben eine Property wie "IsScrolling" oder sowas. Wie kann ich herausfinden, ob der User die Maus auf dem Scrollbalken einer ListBox gedrückt hält?

Folgender Code scrollt zum selektierten Element:

private void Lsb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lsb.Items.Count > 0 && e.AddedItems.Count > 0)
            {
                var newSelectedItem = e.AddedItems[0];
                if (newSelectedItem != null)
                    (sender as ListBox).ScrollIntoView(newSelectedItem);
            }
        }

Edit: "MouseDown" des ScrollViewers feuert leider nicht, wenn ich direkt auf den ScrollBar drücke.

01.07.2019 - 13:47 Uhr

Vermutlich ist das Problem, dass es ein "komplettes" UserControl ist.
Dass was du möchtest ist eher ein Custom Control:

>

Bei Custom Controls trennt man quasi Code und XAML voneinander. Deine Klasse kann dann von einem ContentControl erben.

=)

Dann erstellt mir VS keine XAML datei 🤔

@pinki: Ja es erbt wohl eine Content-Eigenschaft.

01.07.2019 - 13:35 Uhr

Leider verhält es sich dann genauso 😦 Nutze ich den ContentPresenter nicht richtig?

01.07.2019 - 13:13 Uhr

Hallo,

ich möchte ein Control basteln, welches eine spezielle Form hat und aus einem Button besteht, sowie einem Rechteck auf dem der Content als string ausgegeben wird.

Folgendes habe ich bisher:

<UserControl x:Class="UserControlTest.FilterControl"
             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" 
             xmlns:local="clr-namespace:UserControlTest"
             mc:Ignorable="d"
             Height="25" Width="117.833">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="20"/>
        </Grid.ColumnDefinitions>
        <Rectangle Fill="#FFA0A0A0"/>
        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
        <Polygon Grid.Column="1" Points="0,0 20,12.5 0,25" Fill="#FFA0A0A0"/>
        <Button Width="9" Height="9" Grid.Column="1" Margin="2,7.5,8,7.5" Click="Button_Click">
            <Button.Template>
                <ControlTemplate TargetType="Button">
                    <Grid>
                        <Ellipse Stroke="Black" StrokeThickness="1"/>
                        <Line X1="7.5" Y1="7.5" X2="1.75" Y2="1.75" Stroke="Black"/>
                        <Line X1="7.5" Y1="1.75" X2="1.75" Y2="7.5" Stroke="Black"/>
                    </Grid>
                </ControlTemplate>
            </Button.Template>
        </Button>
    </Grid>
</UserControl>

Das sieht soweit im designer ganz gut aus. Instanziiere ich das Ganze nun aber, ist lediglich der text zu sehen und alles andere ist weg. Ausser ich weise keinen Content zu, dann sieht es aus wie im designer.

Was mache ich denn falsch?

Grüße

15.04.2019 - 07:36 Uhr

Hat keiner eine Idee? 😦

11.04.2019 - 19:12 Uhr

Hallo,

ich habe eine UWP-Anwendung worin sich ein AppBarButton befindet, welcher ein Flyout öffnet. Darin befindet sich eine ComboBox. Klicke ich nun auf die ComboBox um ein anderes Item auszuwählen, schließt sich sofort sowohl die ComboBox, als auch das Flyout. Was mache ich falsch?

Dieses Minimalbeispiel reproduziert es:


    <Grid>
        <AppBarButton x:Name="mapSettingsButton" Icon="Map">
            <AppBarButton.Flyout>
                <Flyout Placement="Bottom">
                    <ComboBox Header="Farbstil" SelectedIndex="0">
                        <x:String>Dunkel</x:String>
                        <x:String>Hell</x:String>
                    </ComboBox>
                </Flyout>
            </AppBarButton.Flyout>
        </AppBarButton>
    </Grid>

05.04.2019 - 20:04 Uhr

Zuerst wird ein Element entfernt und dann wieder hinzugefügt. Kann so nicht wissen ob das anfängliche entfernen beachtet werden soll. Checke jetzt im Eventhandler mit IsDragSource() des ListViews einfach ob es gerade beim Drag and Drop ist wenn ein Element entfernt wird. Wenn ja, mache ich einfach nichts weiter. Scheint so zu klappen, wirkt aber nicht wirklich sauber^^
Also falls noch jemandem was einfällt, dann immer raus damit 😃 Ansonsten sag ich dir schon mal danke 😃

05.04.2019 - 14:41 Uhr

Oh entschuldige bitte, das war mir nicht klar. Wie sollte ich denn darauf reagieren? Ich kann nicht feststellen ob das Element nun nur für den Vorgang des Ordnens entfernt/hinzugefügt wurde, oder ich tatsächlich eines entfernt oder hinzugefügt habe.

05.04.2019 - 14:26 Uhr

Hi,

ja dort gibt es "Move". Allerdings tritt dieser Fall nie ein. Das reordering ist bereits im ListView Control implementiert. Dafür müssen nur die Properties "CanReorder" und "AllowDrop" auf true gesetzt werden. Erwähnenswert ist vielleicht das es sich um eine UWP-App handelt...weiß nicht ob das in dem Falle anders als bei WPF ist. ListView scheint aber nicht die "Move()" Methode der ObservableCollection zu nutzen, sondern das Element tatsächlich zu entfernen und an der neuen Stelle wieder einzufügen.

Edit: Könnte vielleicht den Eventhandler beim Start des dragings entfernen, sodass es nicht gefeuert wird und vor dem beenden wieder einfügen. Nur scheint es vom ListView kein event zu geben mit dem ich den Handler wieder anhängen kann bevor das Element wieder eingefügt wird. Aber diese Lösung scheint mir auch irgendwie ziemlich dirty...

05.04.2019 - 13:44 Uhr

Hallo,

ich habe ein Listview, welches via Databinding an eine von ObserableCollection abgeleitete Klasse gebunden ist. Ich möchte darauf reagieren, wenn ein Element verändert, gelöscht, hinzugefügt oder via drag and drop verschoben wird. Nun ist aber das reordering im listview wohl so implementiert, dass das Element entfernt und dann wieder eingefügt wird. Somit wird das Event "CollectionChanged" der ObservableCollection dann immer 2 mal gefreuert 😦 Kann ich das irgendwie umgehen?

Habe keine zufriedenstellende Lösung gefunden...

Vielen Dank,

ByteDevil

11.11.2018 - 18:38 Uhr

Hallo T-Virus,

die Farben an sich interessieren mich danach nicht mehr und ich möchte auch nicht direkt neu zeichnen. Ich brauche die Positionen weil ich mehrere kleine Punkte habe (n viele) die durch die Gegend fliegen. Habe ich nun alle Points die ich brauche, möchte ich sie nur noch auf die Fläche Transformieren auf der sich die Punkte bewegen und dann sollen sie dort hin schweben. Das funktioniert auch prima..brauche nur noch den Point[] 😕

Den bytearray kriege ich von BitmapImage.CopyPixels(). Muss auch nicht unbedingt auf alle Farbwerte prüfen...ist rot schon 0, sind es die anderen auch. Ansonsten möchte ich den Pixel nicht in dem Point[] haben.

11.11.2018 - 18:06 Uhr

Hallo,

Ich habe einen 1 Dimensionalen byte[] welcher die Pixelwerte eines Bildes beinhaltet. Jeder Pixel ist 4 bytes lang und besteht aus je einem Byte für rot, grün, blau und alpha. Das Bild absolut monochom, dh. keine Graustufen sondern entweder ist ein Pixel schwarz (0, 0, 0, 255) oder weiß (255, 255, 255, 255). Nun möchte ich einen Point[] haben, welcher die x und y Koordinaten sämtlicher schwarzen Bildpunkte beinhaltet...aber (und das ist der Teil an dem ich scheitere) ich möchte nur n Punkte haben welche die schwarzen Bereiche im Bild möglichst gut annähern. n ist dabei kleiner als die Anzahl der schwarzen Punkte im Bild.
Ich bin ehrlich gesagt etwas ratlos und meine Versuche sehen immer sehr verzerrt aus weil ich wohl nicht berücksichtigt habe das ich ja auch ganze Zeilen auslassen muss. Komme aber nicht so recht auf die richtige Formel. Kann mir jemand von euch helfen?

So schleife ich sämtliche Pixel des Arrays durch:


int stride = width * 4;
for (int y = 0; y < height; y++)
    for (int x = 0; x < width; x++)
    {
        int index = y * stride + 4 * x;
        // array[index] <- Rot
        // array[index + 1] <- Grün
        // array[index + 2] <- Blau
        // array[index + 3] <- Alpha
     }
08.11.2018 - 20:14 Uhr

Hallo T-Virus 😃

Ja ich zeichne alles alle 100ms um es visualisieren zu können. Du hast recht - es zu Zeichnen wenn es fertig ist wäre sonst natürlich die eigentliche vorgehensweise. Entschuldige, das hätte ich wohl dazu sagen sollen. Also ich möchte sehen können wie das Bild entsteht.

Dieses Phyllotaxis (Anhang) ist zB so etwas. Mache sowas gern weil ich das interessant finde und stunden lang zusehen könnte wie solche Gebilde nach und nach entstehen 😃 Da speichere ich halt jeden berechneten Punkt in einer Liste und zeichne ihn dann alle 100ms. Dabei entstehe dieses Sprialenmuster von innen nach aussen.

Ja an das mit der Grafik habe ich auch schon gedacht...kam mir aber irgendwie hingepfuscht vor und meinst du das würde flüssig aussehen?

08.11.2018 - 19:34 Uhr

Hi,

ich suche nun schon einige Zeit nach etwas geeignetem, allerdings bin ich mir nicht so ganz sicher wonach ich suchen muss. Ich möchte kleinere grafische Simulationen laufen lassen wo immer mal wieder gewisse Bildinhalte dazu kommen. Weiß aber nicht wie ich das Ganze performant hinbekomme.

Bisher zeichne ich immer so:

Ich leite mir eine Klasse von Canvas ab und überschreibe die OnRender() Methode. Darin zeichne ich dann meine Objekte. Nun möchte ich zB alle 100 ms alle meine Objekte zeichnen. Allerdings kommen ständig neue hinzu. Daher muss ich ja alle Objekte in einer Liste haben und ALLE alle 100 ms zeichnen...das wird natürlich recht schnell ruckelig und ich frage mich ob es nicht eine möglichkeit gibt immer nur das zu zeichnen was neu hinzugekommen ist. Geht das mit C#/WPF?

Mann könnte an ein Doppelpendel denken welches sich über längere Zeit bewegt und immer eine Spur auf dem Bildschirm ziehen soll. Müsste mir ja sonst sämtliche Punkte zu jedem Zeitpunkt t merken und sie bei jedem Aufruf von OnRender alle zeichnen...

27.09.2018 - 23:30 Uhr

@herbivore Ja das mit der externen Library fand ich auch nicht so prima, habe mich aber der newtonsoft.json bedient. Ist ja schnell und einfach über nuget installiert und funktioniert prima. Für deinen Exkurs in Regex danke ich dir auch^^ Habe sowas in der Art auch versucht, aber es wollte nicht so recht hin hauen.

Und das Forum ist nun generell auch kein Patterngenerator.

Das ist mir bewusst und es ist ja auch nicht so als hätte ich damit nicht gute 3h genervt gekämpft und auch google um Rat gefragt 😉

26.09.2018 - 23:27 Uhr

Richtig, große Lust hatte ich nicht dazu. Hätte ja sein können das jemand einen kurzen regulären Ausdruck parat hätte, dann wäre es halt nur ein Einzeiler geworden. Habe es so gemacht wie ihr mir geraten habt. Vielen dank für den Hinweis.

26.09.2018 - 19:09 Uhr

Mh aber das was du da siehst ist sehr weit verschachtelt. Das ganze ist aus einem Seitenquelltext der über 500 kb groß ist. Das alles zu deserialisieren bis ich an die eine Information gekommen bin dauert doch ewig 😦 Da steht noch ganz viel anderer Quatsch drin den ich nicht brauche.

Edit: Wobei ich natürlich den Part da oben mit einem Regex suchen und nur diesen Substring deserialisieren könnte...hmmm...am liebsten wäre mir aber ein Regex der das einfach direkt tut^^

26.09.2018 - 18:10 Uhr

Hi,

ich muss aus einem String einen Wert extrahieren, doch die Zusammensetzung ist leider teilweise zufällig bedingt...zumindest die Reihenfolge. Hierzu mal ein Beispiel:


Freunde
[
	{
		Geld: 55,
		Name: "John",
		Laster: {
			Raucht: "Ja",
			Trinkt: "Nein"
		},
		Alter: 18,
		Besitz: {
			Haus: "Ja",
			Boot: "Nein"
		}
	},
	{
		Besitz: {
			Haus: "Nein",
			Boot: "Nein"
		},
		Laster: {
			Raucht: "Nein",
			Trinkt: "Ja"
		},
		Alter: 22,
		Geld: 10,
		Name: "Gary"
	},
	{
		Name: "Eva",
		Laster: {
			Raucht: "Ja",
			Trinkt: "Ja"
		},
		Alter: 44,
		Besitz: {
			Haus: "Ja",
			Boot: "Ja"
		},
		Geld: 30
	}
]

Das steht sonst alles in einer Zeile...also ohne Tabs und ohne Zeilenumbrüche. Nun seht ihr vielleicht auch was mich so stört und zwar das die Felder (tatsächlich sind es deutlich mehr als die paar) immer unterschiedlich angeordnet sind. Könnt ihr mir helfen? Ich möchte zB anhand des Namens das korrekte Alter bekommen. Sprich: Gary->22 oder Eva->44

Bin für jede Hilfe dankbar.

16.06.2018 - 14:03 Uhr

@ByteDevil
Du kannst dir auch einen eigenen NuGet Server aufsetzen und dann bei dir einbinden.
Die Anleitungen dazu findest du bei Google.
Haben wir bei uns auch gemacht um unsere internen Libs zu verteilen.
T-Virus

Ach das geht? Das klingt prima 😃 Denke das werde ich mal versuchen.

Danke euch allen 😃

16.06.2018 - 10:56 Uhr

Danke für die Antworten 😃

Das mit dem Snippet-Editor ist irgendwie nicht so praktisch. Da wird der Code ja tatsächlich jedes mal wieder kopiert und eingefügt 😦 Ist auch ziemlich umständlich gelöst mit diesem XML-Dateien die händisch erstellt werden müssen...

Werde mir wohl wirklich eine eigene Ordnerstruktur überlegen und die in einer Cloud speichern damit ich sie auch auf anderen Rechnern zur Verfügung habe. Ist halt nur blöd weil die Daten auf dem einen Rechner woanders liegen als auf dem an dem ich gerade sitze. Heißt ich muss das jedes mal anpassen wenn ich am Laptop schreibe.

Nuget wäre noch eine Idee, aber dann ist es komplett öffentlich, richtig?

16.06.2018 - 01:02 Uhr

Hallo,

ich programmiere hauptsächlich in C# und mit dem Visual Studio. Im laufe der Jahre hat sich da vieles angehäuft womit ich mir recht viel Mühe gegeben habe und was leicht wiederverwendbar und immer mal wieder nützlich für mich ist. Dann geht jedes mal die Suche los..."wo war das nochmal?" Und dann Copy & Paste wie ein kaputter.

Gibt es nicht vielleicht sowas wie eine Cloud von Microsoft, bei der sich Visual Studio bedienen kann? In die ich meine ganzen Klassen die ich mal geschrieben habe hochladen und dann ganz easy in mein Projekt einbinden kann wenn ich sie brauche? Fände sowas wirklich toll. Kennt ihr sowas?

Viele Grüße,
ByteDevil

16.11.2017 - 22:15 Uhr

Danke für den Link, Abt. Werde es mir morgen mal zu Gemüte führen.

16.11.2017 - 21:09 Uhr

Was ist denn der Unterschied zwischen einem Businessmodell und einer Entity?

Ich habe es jetzt mit einem XmlSerializer implementiert und es sieht ganz gut aus. Das hier hat er mir ausgespuckt:


<?xml version="1.0"?>
<Jobs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <JobArray>
    <JobObjekt xsi:type="ExecuteFileNetworkJob">
      <Delay>100000000</Delay>
      <Message>Browser</Message>
      <FileName>C:\Program Files (x86)\Mozilla Firefox\firefox.exe</FileName>
      <Arguments>-a -b</Arguments>
    </JobObjekt>
    <JobObjekt xsi:type="ShutDownNetworkJob">
      <Delay>200000000</Delay>
      <Message>Shutdown</Message>
    </JobObjekt>
    <JobObjekt xsi:type="RebootNetworkJob">
      <Delay>300000000</Delay>
      <Message>Reboot</Message>
    </JobObjekt>
    <JobObjekt xsi:type="OpenURLNetworkJob">
      <Delay>0</Delay>
      <Message>Website</Message>
      <URL>www.mycsharp.de</URL>
    </JobObjekt>
  </JobArray>
</Jobs>

Gab nur drei Dinge zu beachten: Ich musste in den Ableitungen jeweils einen Standardkonstruktor implementieren, ein TimeSpan lässt sich nicht ohne weiteres serialisieren und ein Objekt vom Typ ProcessStartInfo ebenfalls nicht. ProcessStartInfo hat ja lediglich 2 strings gekapselt welche jeweils eine eigene Property bekamen und der TimeSpan wurde einfach in seine Ticks zerlegt und so gespeichert.

Ich danke euch für den Schups in die richtige Richtung 😃

Viele Grüße,
ByteDevil

16.11.2017 - 18:51 Uhr

pinki, du bist mein Held. Wieder was gelernt. Danke!

Viele Grüße,
ByteDevil

16.11.2017 - 14:08 Uhr

Hallo pinki,

danke für deine Antwort. Kannst du bitte kurz ausführen was du genau mit "in ein neues Template kopieren" meinst? Ein neues Template erstellen und weiter?

Viele Grüße,
ByteDevil

16.11.2017 - 13:25 Uhr

Das mit dem XmlSerializer klingt gar nicht übel. Werde das mal ausprobieren.
Hier mal der gesamte Code:


using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Threading;

namespace NetworkJobScheduler
{
    class NetworkJobCollection : ObservableCollection<NetworkJob> { }

    #region base
    public abstract class NetworkJob : INotifyPropertyChanged
    {
        private TimeSpan delay;
        public TimeSpan Delay
        {
            get { return delay; }
            set { if (delay != value) { delay = value; OnPropertyChanged("Delay"); } }
        }

        private string message;
        public string Message
        {
            get { return message; }
            set { if (message != value) { if (value != string.Empty) message = value; OnPropertyChanged("Message"); } }
        }

        public abstract string Details { get; }
        public string Description { get { return ToString(); } }
        public string DelayString { get { return Delay == TimeSpan.Zero ? "" : Delay.ToString("hh\\:mm\\:ss"); } }

        public event PropertyChangedEventHandler PropertyChanged;

        public virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public void Execute()
        {
            Thread thread = new Thread(Subroutine);
            thread.Start();
        }

        protected abstract void Subroutine();

        public NetworkJob(string msg, TimeSpan? delay) { Message = msg; Delay = delay ?? TimeSpan.Zero; }
    }
    #endregion

    #region Reboot, Shutdown ...
    public class ShutDownNetworkJob : NetworkJob
    {
        public ShutDownNetworkJob(string msg, TimeSpan? delay = null) : base(msg, delay) { }

        public override string Details => "";

        public override string ToString() { return Delay == TimeSpan.Zero ? "Shuts down the computer immediately." : "Shuts down the computer after a while."; }

        protected override void Subroutine()
        {
            Thread.Sleep(Delay);
            var psi = new ProcessStartInfo("shutdown", "/s /t 0")
            {
                CreateNoWindow = true,
                UseShellExecute = false
            };
            Process.Start(psi);
        }
    }

    public class RebootNetworkJob : NetworkJob
    {
        public RebootNetworkJob(string msg, TimeSpan? delay = null) : base(msg, delay) { }

        public override string Details => "";

        protected override void Subroutine()
        {
            Thread.Sleep(Delay);
            var psi = new ProcessStartInfo("shutdown", "/r /t 0")
            {
                CreateNoWindow = true,
                UseShellExecute = false
            };
            Process.Start(psi);
        }

        public override string ToString() { return Delay == TimeSpan.Zero ? "Reboots the computer immediately." : "Reboots the computer after a while."; }
    }
    #endregion

    #region Execute programs, open URL's ...
    public class ExecuteFileNetworkJob : NetworkJob
    {
        private ProcessStartInfo startInfo;
        public ProcessStartInfo StartInfo
        {
            get { return startInfo; }
            set { if (startInfo != value) { startInfo = value; OnPropertyChanged("Details"); } }
        }

        public override string Details => StartInfo.FileName + " " + StartInfo.Arguments;

        public ExecuteFileNetworkJob(string msg, ProcessStartInfo startInfo, TimeSpan? delay = null) : base(msg, delay) { StartInfo = startInfo; }

        protected override void Subroutine()
        {
            Thread.Sleep(Delay);
            Process.Start(StartInfo);
        }

        public override string ToString() { return Delay == TimeSpan.Zero ? "Executes " + Path.GetFileName(startInfo.FileName) : "Executes " + Path.GetFileName(startInfo.FileName) + " after a while"; }
    }
    #endregion
}

Vielleicht möchtet ihr ja im allgemeinen mal drüber schauen. Ein Objekt der NetworkJobCollection ganz oben möchte ich halt speichern.

16.11.2017 - 12:55 Uhr

Hallo T-Virus,

danke für deine Antwort.

Also mit meinem Beispiel meinte ich das auch mehrere Motorräder bzw Autos in der Liste sein können. Hätte ich vielleicht im Beispiel einbauen sollen.
Somit verstehe ich nicht ganz wieso deine Containerklasse ein Objekt von jedem zurückgeben. Meinst du damit ich könnte mir einfach einen Array mit den Objekten von jedem Typen in der Liste ausspucken lassen und das dann einzeln speichern?

Also ich habe mir eine Art Netzwerk Job Scheduler gebastelt, der bei bestimmten Strings die ihm gesendet werden unterschiedliche Dinge tun soll. Diese Jobs habe ich eben auf die oben gezeigte Weise implementiert. Nun habe ich eine Liste (ObservableCollection) mit diesen Jobs und wenn ich mein Programm wieder starte, möchte ich diese Liste natürlich wieder vorfinden. Dafür suche ich jetzt noch eine elegante Art und Weise.

16.11.2017 - 12:36 Uhr

Hallo liebe Community,

gegeben seien folgende Klassen:


abstract class Fahrzeug { public int AnzahlRaeder { get; set; } }

class Auto : Fahrzeug
{
    public int AnzahlTueren { get; set; }
    public Auto(int raeder, int tueren) { AnzahlRaeder = raeder; AnzahlTueren = 4; }
}

class Motorrad : Fahrzeug
{
    public double Kettenspannung { get; set; }
    public Motorrad(double kettenspannung) { AnzahlRaeder = 2; Kettenspannung = kettenspannung; }
}

Welche so instanziiert werden:


List<Fahrzeug> fahrzeuge = new List<Fahrzeug>();
fahrzeuge.Add(new Auto(4, 4));
fahrzeuge.Add(new Motorrad(1));

Angenommen es wären noch deutlich mehr Klassen die auf diese Weise von Fahrzeug erben.
Wie würdet ihr diese Liste nun am besten in einer Datei speichern und sie dann wieder auslesen?

Möchte mir möglichst viel herumgewerfe mit den Unterklassen sparen. Gibt es da von MS vielleicht schon etwas fertiges?

Viele Grüße,
ByteDevil

16.11.2017 - 12:08 Uhr

Hallo,

ich habe ein Control, das von RichTextBox erbt und bei dem ich den BorderBrush auf null gesetzt habe. Dieses Control kommt in dunklen Farben daher, was dafür sorgt, dass der weiße Rahmen der darum gezeichnet wird, wenn man mit der Maus darüber fährt oder es den Fokus erhält, unfassbar hässlich aussieht.
Kann ich dieses Verhalten irgendwie abstellen oder den Rahmen einfärben?

<local:LogConsole x:Name="logConsole" Grid.Row="1" BorderBrush="{x:Null}" Background="#FF464646" Foreground="#FFEFEFEF"/>

Die LogConsole wird im Konstruktor noch auf ReadOnly gesetzt.

Viele Grüße,
ByteDevil

12.11.2017 - 14:54 Uhr

Danke Sir Rufo,

das war es. Funktioniert 😃

Grüße,
ByteDevil

12.11.2017 - 13:06 Uhr

Fehlermeldung:
"Application enthält keine definition für Context." ist die Fehlermeldung. Aber ich denke das hat auch nicht mehr Aussagekraft als das, was ich bereits gesagt habe. Eine Exception gibts nicht, weil ich das so natürlich gar nicht erst compilieren kann.

Es handelt sich übrigens um Xamarin.Forms.Application
Falls die dort auf der Seite sich auf einen anderen Namespace beziehen, könnte das der Fehler sein. Da steht aber nichts - zumindest habe ich nichts davon gesehen.

12.11.2017 - 13:00 Uhr

Habe ich doch geschrieben.

Application hat scheinbar keine Property namens "Context".

12.11.2017 - 12:46 Uhr

Hi,

arbeite zur Zeit an einer Xamarin.Forms Crossplatform App. Dort habe ich eine zur Laufzeit erzeugte Liste von Werten, welche ich in einer XML Datei speichern möchte. Nun bin ich mir aber sehr unsicher wohin damit... Habe hier eine Erklärung gefunden...dort interessiert mich der Absatz "File" wenn ihr ein Stück herunter scrolled.
Ich möchte die Datei so ablegen, das sie mit gelöscht wird, falls meine App deinstalliert wird. Sprich am liebsten in dem zur App gehörenden Verzeichnis. Wisst ihr wie ich das ermittle? Es interessiert mich erstmal nur für Android...wenn es eine Lösung gibt die auch für iOS funktioniert, wäre das natürlich auch toll.

string path = Application.Context.FilesDir.Path;

funktioniert bei mir aber leider nicht. Application hat scheinbar keine Property namens "Context".

Grüße,
ByteDevil

27.10.2017 - 19:36 Uhr

Hallo liebe Community,

ich schreibe gerade etwas, das Strings auf viele Fotos drucken soll. Dabei kann ich festlegen wo genau es hin soll (unten rechts, oben links, etc..).

Das mache ich in etwa so (etwas gekürzt):


Image image = Image.FromFile(file);
using (Graphics g = Graphics.FromImage(image))
{
      StringFormat format = new StringFormat();
      format.Alignment = StringAlignment.Far;
      format.LineAlignment = StringAlignment.Far;
      Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);
      g.DrawString(text, font, new System.Drawing.SolidBrush(color), rect, format);
      image.Save(Path.Combine(outputDir, Path.GetFileName(file)));
}

Soweit klappt das auch, nur leider wird die Schrift bei einigen Bildern manchmal an die völlig falschen Positionen geschrieben...manchmal auf den Kopf, manchmal längs.
Es betrifft immer die Fotos, die in ihren EXIF-Daten zu stehen haben, das sie nicht im Landscape modus geschossen wurden.

Siehe hier
Dort Strg+F und suchen nach "PropertyTagOrientation" oder "0x0112"
Es gibt also 8 unterschiedliche Modi, inklusive gespiegelt, wenn ich Modus 2 richtig verstehe.

Meine Frage ist nun folgende: Wie würdet ihr das Problem lösen? Vor dem verarbeiten des Originalbildes nachsehen, ob das Bild nicht im Modus "1" geschossen wurde und wenn nicht dann die Schrift entsprechend rotieren, oder vielleicht die Exif-Daten des Originalbildes kurz manipulieren und dann wieder auf den vorherigen Wert setzen? Oder gibt es vielleicht eine ganz andere Möglichkeit?

Bin für jeden guten Rat dankbar.

Viele Grüße,
ByteDevil

Edit: Da anscheinend keiner eine bessere Idee hatte, habe ich nun beschlossen die Exif-Daten jedes einzelnen Bildes vorher zu lesen:


enum ImageOrientation { Normal, UpsideDown, RotatedLeft, RotatedRight }

private static ImageOrientation GetImageOrientation(Image image)
{
    if (!image.PropertyIdList.Contains(0x0112)) // PropertyTagOrientation
        return ImageOrientation.Normal;

    foreach (PropertyItem p in image.PropertyItems)
    {
        if (p.Id == 0x0112)
        {
            switch (p.Value[0])
            {
                case 3:
                    return ImageOrientation.UpsideDown;
                case 6:
                    return ImageOrientation.RotatedRight;
                case 8:
                    return ImageOrientation.RotatedLeft;
                default:
                    return ImageOrientation.Normal;
            }
        }
    }

    return ImageOrientation.Normal;
}

und anschließend auszuklamüsern, wie die Schrift zu drehen ist. Hoffe ich kann damit jemandem ewiges Gegrübel ersparen wenn derjenige darüber nachdenkt, warum die Schrift überall ist nur nicht da wo sie sein soll^^ Um die gespiegelten Modis 2, 4, 5 und 7 hab ich mir jetzt allerdings keine Platte gemacht...besitze kein einziges Bild wo das vorkommt.

27.10.2017 - 18:32 Uhr

Oh, das Semikolon habe ich tatsächlich übersehen. Ja so funktioniert es. Ich danke dir vielmals 😃

Grüße,
ByteDevil

27.10.2017 - 17:36 Uhr

Hallo Abt,

danke für deine Antwort.

Also geht das nur wenn es eine Content-Property ist?
Denn

<TextBlock Text="&gt" />

geht nicht. Klar, Text ist in diesem Falle die Content-Property...aber was wenn nicht? Wenn zB in der Tag-Eigenschaft eine spitze Klammer als String stehen soll?

Grüße,
ByteDevil

27.10.2017 - 17:03 Uhr

Hi,

ganz simple Sache sicherlich, aber ich finde nichts darüber wie um Himmels Willen ich eine spitze Klammer (<) in einem String in meinem XAML code escape. Visual Studio denkt ja es würde sich um einen Kommentar handeln. Ich meine aber wirklich einfach das Zeichen.

https://docs.microsoft.com/en-us/dotnet/framework/xaml-services/escape-sequence-markup-extension
Habe ich versucht - geht nicht.

Grüße,
ByteDevil