Laden...

Forenbeiträge von Fab4guy Ingesamt 54 Beiträge

02.03.2021 - 13:38 Uhr

Wieder was gelernt.
Mit der View hast du natürlich recht. Wäre wohl mein nächster Schritt gewesen, wenn ich hier keine Antwort bekommen hätte.

Aber dein zweiter Vorschlag "Hack" funktioniert tadellos. Werde wohl erstmal damit weiter machen.

Vielen Dank für die Aufklärung. 🙂

02.03.2021 - 12:19 Uhr

Hallo zusammen,

ich probiere jetzt seit einiger Zeit bereits diese SQL-Abfrage in C# zu überführen.
Leider hatte ich bisher keinen Erfolg.

So sieht meine SQL-Abfrage aus. Diese funktioniert auch und liefert das gewünscht Ergebnis.


SELECT count(id) as numberOfOrders, 
		SUM(DATEDIFF(DAY, allocatedDate, orderClosedDate)) as average
  FROM orders
  WHERE (allocatedDate is not null AND orderClosedDate is not null and orderClosed = 1) AND 
		(YEAR(allocatedDate) = 2020 AND 
		YEAR(orderClosedDate) = 2020) AND 
		(partNumber LIKE '341911%')

Laut meinen Internet-Recherchen muss ich immer in C# Linq, wenn ich einen Count oder SUM machen will, mit GroupBy arbeiten.
Zumindest habe ich noch kein Beispiel ohne GroupBy gefunden.

Das ist mein bisherigere Stand. Allerdings liefert der, wie erwartet wegen dem GroupBY, das falsche Ergebnis.


            var result = await this.Db.Order
                .GroupBy(g => new { g.Id, g.AllocatedDate, g.OrderClosedDate, g.OrderClosed, g.partNumber})
                .Where(w => (w.Key.AllocatedDate != null && w.Key.OrderClosedDate != null && w.Key.OrderClosed == 1) &&
                (SqlFunctions.DatePart("yyyy", w.Key.AllocatedDate) == 2020 && SqlFunctions.DatePart("yyyy", w.Key.OrderClosedDate) == 2020) &&
                (w.Key.partNumber.StartsWith("341911")))
                .Select(s => new 
                {
                    NumberOfOrders = s.Count(),
                    Average = (int)s.Sum(sum => SqlFunctions.DateDiff("day", sum.AllocatedDate.Value, sum.OrderClosedDate.Value))
                }).ToListAsync();


Kann da jemand helfen?
Viele Grüße

05.04.2020 - 17:19 Uhr

Edit: Du scheinst aber wohl ein Video zu haben, kein Bild - dann schau dir mal
>
an.

Mit dieser Variante funktioniert es. Das entsprechende Attribute ist dieses hier:


 var tempFile = ShellFile.FromFilePath(file);
 Console.WriteLine("file created: " + tempFile.Properties.System.ItemDate.Value);

Merci. Ist also gelöst. 😃

05.04.2020 - 16:44 Uhr

Ist das nicht einfach das Datum mit Uhrzeit, wann die Datei angelegt wurde.
Oder haben Bilder hier nochmal eine eigene Eigenschaft wann diese erzeugt wurden?

T-Virus

Nein ist es leider nicht.

05.04.2020 - 11:27 Uhr

Danke für deine Antwort.
Die TagLib Bib. habe ich direkt mal ausprobiert.
Aber leider ist genau dieses Attribute nicht enthalten oder ich finde es nicht.

Muss ich mir wohl noch deine anderen Vorschläge anschauen 😃

04.04.2020 - 13:34 Uhr

Hallo zusammen,
ich suche ein Lösung wie ich auf das Feld "Medium erstellt" (Siehe Bild im Anhang) einer Datei zugreifen kann.
Kennt dazu jemand einen Weg? Mit FileInfo und so geht das nicht.

Viele Grüße

17.08.2017 - 09:03 Uhr

Mh okay. Aber es reicht nicht aus der vorhanden Methode [HttpGet] daraus zu machen.

17.08.2017 - 08:14 Uhr

Hallo zusammen,

ich würde gerne in meiner Webanwendung mit Ajax-Request arbeiten.
Der Aufbau der Anwendung ist der aus Bild1 und denke ich allgemein bekannt.

Füge ich den Code für den Ajax-Request direkt in der View ein als Script-Teil funktioniert das ganze auch.

Die Methode, welche sich in der extra js-Datei befindet wird über einen Change-Event von diesem Select-Feld aufgerufen.

<div class="formRow">
            <p>
                <label>
                    Land*:<br />
                    <select name="country" id="country" data-url="@Url.Action("FirstAjax","Ajax")">
                        <option value="-1" selected>Bitte wählen</option>
                        <option value="Deutschland">Deutschland</option>
                    </select>
                </label>
            </p>
        </div>

Aktuell zum Testen irgendwelche Testdaten fest verankert.

var frmData = new FormData();
        frmData.append('modul', 'googleMaps');
        frmData.append('street', $('#street').val());
        frmData.append('houseNumber', $('#houseNumber').val());
        frmData.append('zipCode', $('#zipCode').val());
        frmData.append('city', $('#city').val());

        var url = $(this).attr('data-url');

        $.ajax(
            {
                url: url,
                type: 'POST',
                cache: false,
                data: {
                    Address1: "423 Judy Road",
                    Address2: "1001",
                    City: "New York",
                    State: "NY",
                    ZipCode: "10301",
                    Country: "USA"
                },
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    var dataArray = $.parseJSON(data);
                    console.log(dataArray);
                },
                error: function () {
                    alert("Error");
                }
            }
        );

und das ist jetzt der Controller dazu

namespace landscape.Controllers
{
    public class AjaxController : Controller
    {
        // GET: Ajax
        public ActionResult Index()
        {
            return View();
        }
        [HttpPost]
        public ActionResult FirstAjax(Company company)
        {
            return Json(new { success = true });
        }
    }
}

Bild2 zeigt die Fehlermeldung, dass die Datei/Controller nicht gefunden wird.

Die "externen" JS-Dateien werden per Bundle eingespielt.

 @Scripts.Render("~/Scripts/ownJs")

Müsste doch eigentlich genauso funktionieren, als wie wenn ich den Javascript Inline definiere.

01.06.2017 - 18:38 Uhr

Habe eine kleine UI gebaut.
Zwischen den einzelnen Feldern befinden sich labels ohne Inhalt.
In diesen wird im Fehlerfall die Fehlermeldung angezeigt.

Funktioniert auch alles.

Jetzt wollte ich nachträglich über das Main.storyboard ein label verändern.
Ich schaffe es aber nicht dieses auszuwählen da es ja keinen Inhalt hat.

Habe schon wie verrückt rum geklickt.

Jemand eine Idee wie das geht???

31.05.2017 - 21:47 Uhr

Hallo zusammen,

ich habe gerade angefangen mit Xamarin. Aktuell versuche ich meine ersten Testprojekte in dem ich eine IOS-App entwickeln will.
Derzeit probiere gestalte ich eine Login Oberfläche die einen Web-Request absendet und dann im Erfolgsfall den User anmelden soll.

Mein aktuelles Problem/Frage...
Nach Klick auf den Button "Login" wird ein WebRequest gesendet.
Funktionieren tut alles. Also die Daten etc. kommen richtig zurück.
Solange aber auf den Response gewartet wird blockiert die Oberfläche.

Was kann ich dagegen tun.
Hier mein aktueller Code.


partial void CmdLogin_TouchUpInside(UIButton sender)
    {
      lblErrorMail.Text = "";
      lblErrorPassword.Text = "";
      bool error = false;

      if (string.IsNullOrWhiteSpace(txtMail.Text))
      {
        lblErrorMail.Text = "Bitte gib deine E-Mail-Adresse ein.";
        error = true;
      }

      if (string.IsNullOrWhiteSpace(txtPassword.Text))
      {
        lblErrorPassword.Text = "Bitte gib dein Passwort ein.";
        error = true;
      }

      if (error)
        return;
      
      try
      {
        string email = txtMail.Text.Trim();
        string password = txtPassword.Text.Trim();

        WebRequestQuery wrq = new WebRequestQuery("https://www.meine-domain.de/app.php");
        string[] postVariables = { "appRequest", "site", "email", "userPasswort" };
        string[] postValues = { "4%54/45§", "userLogin", email, password };

        wrq.setPostVariables(postVariables);
        wrq.setPostValues(postValues);
        Task<string> responseString = wrq.sendRequestAsync();

        Kicker result = JsonConvert.DeserializeObject<Kicker>(responseString.Result);

        Console.WriteLine(responseString);

      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.InnerException);

      }

    public Task<string> sendRequestAsync()
    {

      return Task.Factory.StartNew(() =>
      {
        this.buildPostString();

        if (string.IsNullOrWhiteSpace(this.postString))
          throw new ArgumentException("Parameter cannot be null", "postString");

        HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(this.url);

        ASCIIEncoding encoding = new ASCIIEncoding();
        byte[] data = encoding.GetBytes(this.postString);

        httpWReq.Method = "POST";
        httpWReq.ContentType = "application/x-www-form-urlencoded";
        httpWReq.ContentLength = data.Length;

        using (Stream stream = httpWReq.GetRequestStream())
        {
          stream.Write(data, 0, data.Length);
        }

        HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
        string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

        if (responseString.Length > 0)
        {
          int len = responseString.Length > 0 ? responseString.Length - 1 : 0;
          responseString = responseString.Substring(0, len);
          responseString = responseString.Substring(1);
        }
        else
        {
          responseString = null;
        }

        return responseString;
      });


    }
25.04.2017 - 18:57 Uhr

Ich versuche ich mich gerade an einer App für IOS mit Visual Studio und Xamarin.

Dazu möchte ich Daten von einer Internetschnittstelle abrufen.

Die php-Datei auf dem Webserver erwartet einen bestimmtes Post-Array und liefert bei Erfolg json zurück.

Mit diesem Codeausschnitt spreche ich die php-Datei an und erhalte auch json zurück.


        string url = "https://www.muster.de/app.php";

        HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create( url );

        ASCIIEncoding encoding = new ASCIIEncoding();
        string email = txtMail.Text.Trim();
        string password = txtPassword.Text.Trim();

        string postData="appRequest=76/%&nh()2";
        postData += ( "&site=login" );
        postData += ( "&email=" + email );
        postData += ( "&userPasswort=" + password );

        byte[] data = encoding.GetBytes(postData);

        httpWReq.Method = "POST";
        httpWReq.ContentType = "application/x-www-form-urlencoded";
        httpWReq.ContentLength = data.Length;

        using (Stream stream = httpWReq.GetRequestStream())
        {
          stream.Write(data, 0, data.Length);
        }

        HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();

        string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
        
        Console.WriteLine(responseString);


        Kicker result = JsonConvert.DeserializeObject<Kicker>(responseString);

Das kommt beim responseString raus. (Sieht für mich richtig aus.)

[{"email":"mail@dlrg-kickers.de","firstname":"Max","lastname":"Mustermann","id":"1","position":"Sturm","height":"181","birthday":"2012-12-11","strongFoot":"rechts"}]

Mit using Newtonsoft.Json; für ich gerne den JsonString in ein Objekt der Klasse Kicker parsen.
Das ist die Klasse Kicker

using System;

namespace kickers
{
  public class Kicker
  {

    public String firstname { get; set; }

    public String lastname { get; set; }

    public String email { get; set; }

    public int kickerID { get; set; }

    public String position { get; set; }

    public int height { get; set; }

    public DateTime birthday { get; set; }

    public String strongFoot { get; set; }

  }
}

Allerdings erhalte ich immer diese Fehlermeldung.

Fehlermeldung:
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'kickers.Kicker' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.

Jemand eine Idee was ich falsche mache? Mein JsonString ist doch richtig aufgebaut???

12.12.2016 - 11:15 Uhr

Es liegt gar nicht an den Threads. Glaube ich!

Kann das sein, dass "renderTargetBitmap" außerhalb des Scope liegt, wenn ich probiere in diesem Teil Application.Current.Dispatcher.... darauf zu zugreifen?

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(this.webcamBoxWidth, this.webcamBoxHeight, this.left, this.top, PixelFormats.Pbgra32);

                     Application.Current.Dispatcher.Invoke(new Action(() =>
                     {
// Also alles was hier passiert ist auch nur hier verfügbar.
                         renderTargetBitmap.Render(this.mw.webcamBox); // Ist ein Canvas-Element aus dem UI-Thread
                     }));

                     PngBitmapEncoder pngImage = new PngBitmapEncoder();
                     pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));

                     using (Stream fileStream = File.Create(this.currentPath + "\\" + this.currentFilename + ".png"))
                     {
                         pngImage.Save(fileStream);
                     }

12.12.2016 - 10:40 Uhr

Die Theorie ist glaube ich schon klar.

Wenn ich das Element nur verstecke, funktioniert es auch.


                  Application.Current.Dispatcher.Invoke(new Action(() =>
                    {
                        //renderTargetBitmap.Render(this.mw.webcamBox.);
                       this.mw.webcamBox.Visibility = Visibility.Hidden;
                    }));

Das ist mein MainWindow

namespace qr
{
    public partial class MainWindow : Window
    {
        private webcam wc;
        private qrCodeReader qrCodeReader;

        public MainWindow()
        {
            InitializeComponent();
            this.wc = new webcam(this);
            this.qrCodeReader = new qrCodeReader(this);
        }

        #region 
        private void qrCodeScanner_Loaded(object sender, RoutedEventArgs e)
        {
            this.wc.searchVideoSources();
            this.wc.startVideoStream();
        }

        private void qrCodeScanner_Closed(object sender, EventArgs e)
        {
            this.wc.closeWebcamStream();
        }

        private void cmdStartScan_Click(object sender, RoutedEventArgs e)
        {
            Thread thread = new Thread(this.qrCodeReader.startScan);
            thread.Start();
        }

        private void cmdSelectFile_Click(object sender, RoutedEventArgs e)
        {

        }

        private void cmdStopScan_Click(object sender, RoutedEventArgs e)
        {

        }
        #endregion
    }
}
12.12.2016 - 08:38 Uhr

Die Webcam wird jetzt im Canvas-Element dargestellt.
Funktioniert einwandfrei.

Jetzt möchte ich gerne, dass wenn ein Button geklickt wird ständig "Bilder" von der Webcam gemacht werden und in einem Ordner gespeichert werden.

Habe Problem mit dem Threading. Da ich diese Aktion in einem extra Thread ausführen will, da sonst die Anwendung ja einfriert.

So ist mein Aufruf.

        private void cmdStartScan_Click(object sender, RoutedEventArgs e)
        {
            Thread thread = new Thread(this.qrCodeReader.startScan);
            thread.Start();
        }
public void startScan()
        {
            
            /*String pathExtensionFolder = "\\webcamImages";
            this.newPathOfImageFolder = path + pathExtensionFolder;*/
            
            Random rnd = new Random();

           /* if (!Directory.Exists(path + pathExtensionFolder))
                Directory.CreateDirectory(path + pathExtensionFolder);*/

            while (!this.qrCodeReadSuccess)
            {
                try
                {
                    this.currentFilename = rnd.Next(1, 100000000);

                    RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(this.webcamBoxWidth, this.webcamBoxHeight, this.left, this.top, PixelFormats.Pbgra32);

                    Application.Current.Dispatcher.Invoke(new Action(() =>
                    {
                        renderTargetBitmap.Render(this.mw.webcamBox); // Ist ein Canvas-Element aus dem UI-Thread
                    }));

                    this.mw.Dispatcher.Invoke((Action)(() =>
                    {
                        renderTargetBitmap.Render(this.mw.webcamBox); // Ist ein Canvas-Element aus dem UI-Thread
                    }));


                    PngBitmapEncoder pngImage = new PngBitmapEncoder();
                    pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));

                    using (Stream fileStream = File.Create(this.currentPath + "\\" + this.currentFilename + ".png"))
                    {
                        pngImage.Save(fileStream);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                #region
                /*using (Bitmap bmp = new Bitmap(webcamBoxWidth, webcamBoxHeight))
                {
                    this.currentFilename = rnd.Next(1, 100000000);


                    this.mw.webcamBox.DrawToBitmap(bmp, webcamBox.ClientRectangle);
                    this.mw.webcamBox.

                    bmp.Save(path + pathExtensionFolder + "\\" + this.currentFileName + ".jpg", ImageFormat.Jpeg);
                }*/

                //readQrCodeImage(path, pathExtensionFolder);
                #endregion
            }
        }

Funktioniert leider nicht. Es knallt immer beim Zugriff auf das Canvas Element.
also hier renderTargetBitmap.Render(this.mw.webcamBox);.

Kann ich das irgendwie lösen?

09.12.2016 - 15:17 Uhr

Puh, kann ich ehrlich gesagt schon gar nicht mehr sagen.
Habe so viele Möglichkeiten probiert gehabt.

Die mit Canvas geht ja jetzt.

09.12.2016 - 14:59 Uhr

Das hatte ich schon versucht. Allerdings ohne Erfolg.

09.12.2016 - 14:29 Uhr

Habe gerade eine Möglichkeit gefunden.

Benutzte jetzt ein Canvas-Element und wandle vorher das Bitmap in Media.Brush um.


        public static System.Windows.Media.Brush CreateBrushFromBitmap(Bitmap bmp)
        {
            return new ImageBrush(Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()));
        }

09.12.2016 - 14:22 Uhr

Ich habe eine kleine Windows.Forms.Anwendung, welche mir die Bilder aus der Webcam in einer pictureBox anzeigt.

Funktioniert auch alles wunderbar.
Dies ist der Teil, bei dem die Bilder an die picutureBox gebunden werden.


        private void videoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
        {
            //Jedes ankommende Objekt als Bitmap casten und der Picturebox zuweisen
            //(Denkt an das ".Clone()", um Zugriffsverletzungen aus dem Weg zu gehen.)
            try
            {
                webcamBox.BackgroundImage = (Bitmap)eventArgs.Frame.Clone();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

Jetzt will ich die Anwendung in eine WPF-Anwendung übernehmen.
Das Problem was ich aktuell habe ist, dass es bei WPF keine pictureBox gibt sondern nur ein Image Control.

Und bei dem ImageControl wird an die Source-Property gebunden anstatt wie bei der pictureBox an das Background-Property.


        private void videoSource_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
        {
            //Jedes ankommende Objekt als Bitmap casten und der Picturebox zuweisen
            //(Denkt an das ".Clone()", um Zugriffsverletzungen aus dem Weg zu gehen.)
            try
            {
                Bitmap img = (Bitmap)eventArgs.Frame;
                
                //this.mw.webcamBox.Source = (ImageSource)eventArgs.Frame.Clone();
                //ImageSource imageSource = new BitmapImage(new Uri("C:\\Users\\NLAUING\\Desktop\\qrcode.jpeg"));
                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    this.mw.webcamBox.Source = img;
                    //this.mw.webcamBox.Source = new BitmapImage(new Uri(bitmapImage, UriKind.RelativeOrAbsolute));
                }));
     
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


Dummerweise akzeptiert das Image-Control keine Bitmap.> Fehlermeldung:

"Eine implizite Konvertierung von Typ 'System.Drawing.Bitmap' in 'System.Windows.Media.ImageSource' ist nicht möglich".

Kennt jemand eine Möglichkeit?
Oder empfiehlt sich ein anderes Control?

05.12.2016 - 11:34 Uhr

Hallo zusammen,

kennt jemand eine Möglichkeit wie man automatisch nach n Zeichen einen Zeilenumbruch einfügen kann.

Und das dann auch in jeder neuen Zeile.
Also jede Zeile darf maximal n Zeichen enthalten und dann wird sie umgebrochen.

30.11.2016 - 11:24 Uhr

Das versuche ich ja, aber es kommt immer, dass es die Property-Eigenschaft Template nicht erkannt wurde oder es konnte nicht auf den Member zugegriffen werden.

Müsste doch so anfangen?


<Style x:Key="buttonPayed" TargetType="{x:Type TextBlock}">
........
<Setter Property="Template">
........
</Setter>[XML]
30.11.2016 - 10:50 Uhr

Ja Top! Funktioniert!

Hast du auch eine Idee, wie ich bei MouseOver die Farbe ändern kann`?

30.11.2016 - 10:21 Uhr

Okay, dass ist cool!

Kann ich diese auch als Style-Source anlegen.

Hatte das bisher bei Buttons immer so gemacht.


    <Style x:Key="buttonNavigation" TargetType="{x:Type Button}">
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="Foreground" Value="#FFFFFF" />
        <Setter Property="FontSize" Value="12" />
        <Setter Property="Cursor" Value="Hand"/>
        <Setter Property="Height" Value="60"/>
        <Setter Property="FontFamily" Value="Calbri"/>
        <Setter Property="Width" Value="70"/>

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid Background="{TemplateBinding Background}">
                        <WrapPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center" Background="{TemplateBinding Background}">
                            <fa:ImageAwesome Height="15" Icon="Money" Foreground="{TemplateBinding Foreground}" Margin="0,0,0,5" />
                            <ContentPresenter x:Name="MyContentPresenter" Content="{TemplateBinding Content}" />
                        </WrapPanel>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="#64b5f6" />
                            <Setter Property="Foreground" Value="#000000" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Wenn ich aber bei TargetType einen Border anlege, gibt es unten die Eigenschaft Template nicht mehr.

Wobei ich gerade gemerkt habe, dass der Klick auch "nur" auf das Logo und die Schrift geht und nicht auf den kompletten Button

30.11.2016 - 10:04 Uhr

Ja das habe ich gemacht.
Allerdings funktioniert der Link dann nur, wenn man auf den Text vom Hyperlink klickt.

30.11.2016 - 09:42 Uhr

Gibt es eigentlich in WPF eine Möglichkeit, einen Hyperlink so zugestalten, dass er aussieht wie ein Button?

<Hyperlink NavigateUri="/employee.xaml" Foreground="#FFFFFF" TextDecorations="none">Mitarbeiter</Hyperlink>
18.11.2016 - 08:53 Uhr

Ich habe eine TextBox die nur Zahlen-Eingabe zulässt und diese dann in ein Währungsformat formatiert.

Funktioniert soweit auch.

Allerdings wenn ich jetzt 49 eingebe, steht in der TextBox 94.
Sprich es wird immer die neue Zahl vor die andere geschrieben statt dahinter.

Was kann ich dagegen tun?


        private void txtCurrency_TextChanged(object sender, TextChangedEventArgs e)
        {
            decimal number;
            if (decimal.TryParse(txtCurrency.Text, out number))
            {
                txtCurrency.Text = String.Format("{0:#,##0.00}", number);
            }
            else
            {
                txtCurrency.Text = "";
            }
        }

16.11.2016 - 13:20 Uhr

Ich komme aus der Webentwicklung und bin noch relativ neu in C# wpf.

Aktuell stehe ich vor der Frage, wie ich eine WFP-Browseranwendung erstelle die aus mehreren Seiten besteht und der Header und die Navigation auf allen Seiten ja dieselbe sein soll.

Ich stelle mir das so vor, dass ich eine Page Navigation.xaml und eine Page Header.xaml anlege.

Diese Pages würde ich dann gerne irgendwie per "include" auf jeder Seite einbinden.

Falls es eine Änderung im Header oder der Navigation gibt, dass es nur an einer Stelle abgeändert werden muss.

Kann mir jemand einen Ansatz sagen wie die Controls/Elemente wie auch immer heißen???

16.11.2016 - 12:53 Uhr

Habe das Problem jetzt so "gelöst" indem ich der Page das Event "Loaded" angehängt habe. Dort setzte ich dann canuseraddrows auf false.

Damit kann ich jetzt erstmal leben.

11.11.2016 - 13:12 Uhr

Hatte mich getäuscht.
Das Problem besteht weiterhin!
SORRY

Kann man nicht einfach die letzte Zeile irgendwie ausblenden?

09.11.2016 - 13:09 Uhr

Ist erledigt funktioniert nun!

08.11.2016 - 13:53 Uhr

Was anderes nebenbei...

Wenn ich das so wie untenstehend in meinem Grid definiere, kann ich aus dem Code raus nicht auf den Expander (dataGridExpander) zugreifen um die Eigenschaft isExpanded zu ändern.

Lösche ich <DataGrid.GroupStyle>, <GroupStyle>, <GroupStyle.ContainerStyle>, <Style TargetType="{x:Type GroupItem}">, <Setter Property="Template">, <Setter.Value>, <ControlTemplate TargetType="{x:Type GroupItem}">

habe ich Zugriff, allerdings funktioniert das Grid dann nicht mehr.
Es kommt dann immer die Meldung:

Items collection must be empty before using ItemsSource.


                <DataGrid.GroupStyle>
                    <GroupStyle>
                        <GroupStyle.ContainerStyle>
                            <Style TargetType="{x:Type GroupItem}">
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type GroupItem}">
                                            <Expander x:Name="dataGridExpander" IsExpanded="False" Style="{StaticResource dataGridGroupExpander}">
                                                <Expander.Header>
                                                    <Grid Height="40">
                                                        <Grid.ColumnDefinitions>
                                                            <ColumnDefinition Width="250"></ColumnDefinition>
                                                            <ColumnDefinition Width="270"></ColumnDefinition>
                                                            <ColumnDefinition Width="*"></ColumnDefinition>
                                                            <ColumnDefinition Width="*"></ColumnDefinition>
                                                        </Grid.ColumnDefinitions>
                                                        <StackPanel Orientation="Horizontal" Grid.Column="0">
                                                            <TextBlock Text="{Binding Items[0].Name}" VerticalAlignment="Center" />
                                                        </StackPanel>
                                                        <StackPanel Orientation="Horizontal" Grid.Column="1" >
                                                            <TextBlock Text="[" VerticalAlignment="Center" Margin="0,0,5,0"/>
                                                            <TextBlock Text="{Binding Items[0].Anzahl}" Margin="0,0,5,0" VerticalAlignment="Center"  />
                                                            <TextBlock Text="{DynamicResource gridNumberOfWorksteps}"  VerticalAlignment="Center" />
                                                            <TextBlock Text="]" VerticalAlignment="Center" Margin="5,0,0,0"/>
                                                        </StackPanel>
                                                        <Button Grid.Column="2" HorizontalAlignment="Right" Name="cmdDeleteProcess" Tag="{Binding Items[0].ID_Vorgaenge}" Style="{StaticResource buttonDelete}" ToolTip="{DynamicResource buttonDeleteProcess}" Click="cmdDeleteProcess_Click" Margin="0,0,15,0" />
                                                        <Button Grid.Column="3" HorizontalAlignment="Right" Style="{StaticResource buttonAdd}" Tag="{Binding Items[0].ID_Vorgaenge}" ToolTip="{DynamicResource buttonAddWorkStep}" Click="cmdAddWorkStep_Click" >
                                                            <TextBlock Text="{DynamicResource buttonAddWorkStep}" />
                                                        </Button>
                                                    </Grid>
                                                </Expander.Header>
                                                <ItemsPresenter />
                                            </Expander>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </GroupStyle.ContainerStyle>
                    </GroupStyle>
                </DataGrid.GroupStyle>

08.11.2016 - 13:05 Uhr

Ich habe jetzt folgendes feststellen können.

Ich habe auch eine Gruppierung in meinem Datagrid.

Wenn ich beim Expander die Eigenschaft isExpanded="True" setze dann funktioniert ist.

Ist beim ERSTEN laden des DataGrid alles zugeklappt funktioniert es nicht.

Klappe ich aber dann eine Zeile mal auf und aktualisiere mein Grid dann über einen Button, also lade die Daten neu rein, dann passen die Header plötzlich.

08.11.2016 - 12:06 Uhr

So geht es ja auch.
Setzte mal CanUserAddRows auf False.

Dann sollte es nicht mehr gehen.

08.11.2016 - 10:59 Uhr

Bei meinem Datagrid hätte ich gerne, dass sich die Spalten immer der Fenstergröße anpassen.

Das funktioniert auch, wenn ich folgende Einstellungen benutze.


<Style x:Key="mainGrid" TargetType="{x:Type DataGrid}">
<Setter Property="ColumnWidth" Value="*" />
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="IsReadOnly" Value="False" />
<Setter Property="CanUserAddRows" Value="True" />
<Setter Property="CanUserResizeColumns" Value="True" />
<Setter Property="GridLinesVisibility" Value="none" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="RowHeaderWidth" Value="0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="MinRowHeight" Value="50" />
</Style>

Allerdings habe ich ja bei dieser Konfiguration am Schluss die leer Zeile.
Wegen CanUserAddRows = True.

Setzte ich CanUserAddRows auf False, dass die Spalte wegfällt. Ist die Zeile zwar weg aber dafür sind meine Spalten klein. Siehe Bild.

Jemand eine Idee wie ich das hinbekomme, dass meine Spalten immer maximal breit sind und die leere Zeile verschwindet?

Habe schon alle möglichen Kombinationen durch probiert auch mit IsReadOnly usw.

07.11.2016 - 08:52 Uhr

Ich habe ein DataGrid, bei dem die Zeilen auch über Zeilen-Details verfügen.
Klickt man eine Zeile an, werden die Details der Zeile sichtbar.

Nun hätte ich eigentlich erwartet, da dies auch die Benutzer erwarten, das ein weiterer Klick auf die selbe Zeile die Details wieder schließt.

Leider ist das nicht so.

Als Standardfunktionalität scheint es dies nicht zugeben.
Da es nur diese Optionen gibt. Collapsed, Visible, VisibleWhenSelected

Bei Stackoverflow habe ich eine Variante gefunden die das über einen Button löst. Siehe hier

Allerdings will ich nicht extra für diese Funktion einen extra Button.

Kennt jemand eine Möglichkeit dies umzusetzen, wie ich mir das vorstelle?

06.11.2016 - 17:23 Uhr

Hallo zusammen,

kennt jemand eine einfache Möglichkeit, beim "Datepicker"-Element die Kalenderwochen mit anzuzeigen?

Bin verwundert, dass diese keine Standardfunktionalität ist.

15.10.2016 - 19:47 Uhr

Habe es jetzt so gemacht. Funktioniert jetzt wunderbar.. 😃

15.10.2016 - 18:22 Uhr

Was ich aktuelle tue:
Ich bekommen Daten aus einer SQL-Datenbank die in eine DataTable Objekt geschrieben werden.

Diese Daten werden dann in eine Excel-Tabelle geschrieben.
Auf die Daten-Range wird dann ein TabellenStyle angewendet.

Funktioniert auch alles soweit.
Was ich bis jetzt nicht hin bekommen habe, ist das der Autofilter von der Tabelle meine Überschriften verwendet als Tabellenüberschriften.

Aktuell wird immer Spalte1, Spalte2, Spalte2 usw. angezeigt.

Jemand eine Idee??


                Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
                excel.Workbooks.Add();
                Microsoft.Office.Interop.Excel.Worksheet workSheet = excel.ActiveSheet;

                int rowIndex = 0;
                int columnIndex = 0;
                foreach (DataColumn colum in this.currentExportTable.Columns)
                {
                    workSheet.Cells[rowIndex + 1, columnIndex + 1] = colum.ColumnName;
                    columnIndex++;
                }
                rowIndex++;

                foreach (DataRow row in this.currentExportTable.Rows)
                {
                    for (columnIndex = 0; columnIndex < row.ItemArray.Length; columnIndex++)
                    {
                        workSheet.Cells[rowIndex + 1, columnIndex + 1] = row.ItemArray[columnIndex];
                        workSheet.Columns[columnIndex + 1].Autofit();
                    }
                    rowIndex++;
                }
                workSheet.Name = this.currentUser.getUserFirstname() + " " + this.currentUser.getUserLastname();

                Microsoft.Office.Interop.Excel.Range last = workSheet.Cells.SpecialCells(Microsoft.Office.Interop.Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
                Microsoft.Office.Interop.Excel.Range range = workSheet.get_Range("A1", last);

                workSheet.ListObjects.AddEx(Microsoft.Office.Interop.Excel.XlListObjectSourceType.xlSrcRange, range, Type.Missing, Microsoft.Office.Interop.Excel.XlYesNoGuess.xlNo, Type.Missing).Name = workSheet.Name;
                workSheet.ListObjects.get_Item(workSheet.Name).TableStyle = "TableStyleMedium2";
                workSheet.ListObjects.get_Item(workSheet.Name).ShowHeaders = false;
                excel.Application.Visible = true;

13.10.2016 - 19:02 Uhr

Okay.

Also lade ich wie gehabt die Daten in das DataTable Objekt?
Iteriere über jede Spalte und Zeile und erstelle dann für jeder Zeile
ein Objekt von


public class ItemViewModel
 {
   public string FileName { get; set; }
   // usw. ...
 }


und packe es danach in die Liste.

Die Liste binde ich dann an das DataGrid?

Habe das noch nie so gemacht, weil ich es noch nie wirklich verstanden habe.
Vielleicht ja jetzt.

Probiere ich gleich morgen aus.
Bin um jede weitere Hilfe und Tipps dankbar.
Und wenn ich oben quatsch geschrieben habe, kannst es ruhig sagen 😉

13.10.2016 - 18:45 Uhr

Ja ich weiß doch. 😉

Der schreibt scheinbar tatsächlich nicht die Liste mit Objekten in die Spalte sondern den blöden String was es ist.

13.10.2016 - 18:28 Uhr

Welche Daten dabei an das ItemsControl übergeben werden, siehst du doch, wenn du einfach einen Breakpoint in deine Converter-Methode setzt, siehe nochmal: [Artikel] Debugger: Wie verwende ich den von Visual Studio?.

Das mache ich ja die ganze Zeit.
Ich blicks einfach nicht was der da macht.
Siehe Bild: So Dinge stehen da immer drin. Aber nie ein ganzer String.

13.10.2016 - 18:06 Uhr

Wow! Da war ich nur mal kurz einkaufen und schon so viele Antworten.
Klasse und Danke! 👍 👍

Habe jetzt ein bisschen weiter probiert. Aber leider immer noch kein Erfolg erzielen können.

@Sir Rufo:

Und das leeren der Liste

filePathes.Clear();

ist allerdings eher kontraproduktiv.

Wofür füllen, wenn man die dann doch wieder leert. Das sollte wohl eine neue Instanz werden Augenzwinkern

Hast recht. 😉

@lutzeslife

  
foreach (var row in table.Rows)  
             {  
                 var pathAsString = row["Verlinkungen"] as string;  
  
                 if(string.IsNullOrEmpty(pathes) || string.IsNullOrWhiteSpace(pathes)) continue;  
  
                 var pathes = paths.Split(new string[]{";"},StringSplitOptions.RemoveEmptyEntries).ToList();  
  
                 row.SetField("Verlinkungen_Verlinkungen", pathes);  
             }   

Hatte ich genau so umgesetzt. Das Ergebnis ist genau wie bei mir. Bzw. das ich halt jetzt lauter TextBoxen bekomme anstatt die einzelnen Zeichen.

Mein aktueller Stand.


           List<object> filePathes = new List<object>();
           foreach (DataRow row in table.Rows)
            {
                if (row["Verlinkungen"].ToString().Trim() != "")
                {
                    String[] pathes = row["Verlinkungen"].ToString().Split(';');
                    foreach (object path in pathes)
                    {
                        filePathes.Add(path);
                    }

                    row.SetField("Verlinkungen", filePathes);
                    filePathes = new List<object>();
                }
            }


                                    <ItemsControl ItemsSource="{Binding Verlinkungen}">
                                        <ItemsControl.ItemTemplate>
                                            <DataTemplate>
                                                <TextBlock>
                                                    <Hyperlink Click="openFile_Click" TargetName="{Binding}" ToolTip="{Binding}" TextDecorations="{x:Null}">
                                                        <Image Source="{Binding Converter={StaticResource stringToImageConverter}}" Width="30" Height="30" />
                                                    </Hyperlink>
                                                </TextBlock>
                                            </DataTemplate>
                                        </ItemsControl.ItemTemplate>
                                    </ItemsControl>

?


        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            String extension = Path.GetExtension(value.ToString());
            String imagePath = null;

             switch (extension.ToLower())
             {
                 case ".xlsx":
                 case ".xls":
                     imagePath = "icons/table_excel.png";
                     break;
                 case ".docx":
                 case ".doc":
                     imagePath = "icons/page_white_word.png";
                     break;
                 case ".pdf":
                     imagePath = "icons/file_extension_pdf.png";
                     break;
             }
             return imagePath;
        }

Nur mal zum Verständnis.
Beim dem ItemSource kommt im Normalfall eine Liste an.
Erstellt das ItemControl dann so viele Felder wie Einträge in der Liste?
Und steht im Binding vom schon der Inhalt der einzelnen Listeneinträge dann?

13.10.2016 - 15:23 Uhr

Tut mir leid, aber das ist nicht der Fehler.
Und ich weiß wie man den Debugger verwendet. ⚠ 😜

Schau dir lieber mal den Code vorher an.. 😉

13.10.2016 - 15:16 Uhr

Also ich iteriere jetzt über meine DataTable-Objekt und immer, wenn das entsprechende Feld nicht leer ist, baue ich eine List zusammen.

Danach bin ich das DataTable-Objekt an mein Grid.

Hier der Code-Ausschnitt.


           List<String> filePathes = new List<String>();
            foreach (DataRow row in table.Rows)
            {
                if (row["Verlinkungen"].ToString().Trim() != "")
                {
                    String[] pathes = row["Verlinkungen"].ToString().Split(';');
                    foreach (String path in pathes)
                    {
                        filePathes.Add(path);
                    }

                    row.SetField("Verlinkungen_Verlinkungen", filePathes);
                    filePathes.Clear();
                }
            }
            
            ListCollectionView lcv = new ListCollectionView(table.DefaultView);
            PropertyGroupDescription group = new PropertyGroupDescription("ID");
            lcv.GroupDescriptions.Add(group);
            this.dataGrid.ItemsSource = null;
            this.dataGrid.ItemsSource = lcv;
            this.dataGrid.UnselectAll();

Das Item-Control Element gibt mir jetzt im DataGrid folgendes aus. ?( ?(

13.10.2016 - 09:15 Uhr

Der String kommt direkt aus einer SQL-Datenbank.
Das Select füllt direkt ein DataTable, welches dann direkt an das DataGrid gebunden wird.

Mh dann müsste ich quasi über das DataTable-Element iterieren und immer, wenn so ein String da ist diese ersetzten durch eine Liste.

13.10.2016 - 08:07 Uhr

Leider bekomme ich ja keine Liste.
Sondern einen String der so aussieht.

C:\Drivers\datei.pdf;D:\neuerOrdner\word.doc;E:\nocheinOrdner\xyz\x.pdf

12.10.2016 - 19:45 Uhr

Ich habe keine Ahnung, ob das was ich will, möglich ist oder ob multibinding der richtige Ausdruck dafür ist.
Aber es hört sich mal gut an. 😃

Momentaner Stand:
Ich habe ein DataGrid bei dem auch Verweise auf Dateien angezeigt werden.
Klickt man auf einen Verweis (im Prinzip ein Link auf eine Datei auf einem Laufwerk) wird diese Datei aufgerufen und angezeigt.

Das funktioniert auch alles einwandfrei.
Hier ein kleiner Ausschnitt vom aktuellen Stand.


<TextBlock>
    <Hyperlink Click="openFile_Click" TargetName="{Binding FilePath}" TextDecorations="{x:Null}">
        <Image Source="{Binding FilePath, Converter={StaticResource stringToImageConverter}}" Width="30" Height="30" />
    </Hyperlink>
</TextBlock>


public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    String extension = Path.GetExtension(value.ToString());
    String imagePath = null;

    switch(extension.ToLower())
    {
       case ".xlsx":
       case ".xls":
              imagePath = "icons/excel.png";
        break;
       case ".docx":
       case ".doc":
              imagePath = "icons/word.png";
        break;
       case ".pdf":
              imagePath = "icons/pdf.png";
        break;
    }
    
    return imagePath;
}

Was ich also tue. Ich bekomme einen simplen Pfad wo eine bestimmte Datei liegt. Schaue welche Endung das ist und gebe dementsprechend das passende Bild zurück.
Das funktioniert auch alles einwandfrei solange es um einen Pfad geht.

Was aber, wenn ich jetzt das ganze mit n-Pfaden machen will und diese in einem String kommen die jeweils durch ein ; getrennt sind.

Mein Ansatz wäre irgendwie dieser.


<Placeholder Binding{Binding FilePath, Converter={StaticResource stringToImageConverter}} />


public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    String[] pathes = value.ToString().Split(';');

    jetzt eine Foreach über die einzelne Pfade und das dementsprechende Bild zurück geben.

    String extension = Path.GetExtension(value.ToString());
    String imagePath = null;

    switch(extension.ToLower())
    {
       case ".xlsx":
       case ".xls":
              imagePath = "icons/excel.png";
        break;
       case ".docx":
       case ".doc":
              imagePath = "icons/word.png";
        break;
       case ".pdf":
              imagePath = "icons/pdf.png";
        break;
    }
    
    return imagePath;
}

und danach muss der Converter quasi N solcher Blöcke ja zurückgeben und der Placeholder wird ersetzt.
(Placeholder habe ich mir jetzt einfach mal ausgedacht)


<TextBlock>
    <Hyperlink Click="openFile_Click" TargetName="C:\irgendwas" TextDecorations="{x:Null}">
        <Image Source="icons/word.png" Width="30" Height="30" />
    </Hyperlink>
</TextBlock>

<TextBlock>
    <Hyperlink Click="openFile_Click" TargetName="C:\irgendwasNeues" TextDecorations="{x:Null}">
        <Image Source="icons/pdf.png" Width="30" Height="30" />
    </Hyperlink>
</TextBlock>

<TextBlock>
    <Hyperlink Click="openFile_Click" TargetName="C:\irgendwasNeuesNochMehr" TextDecorations="{x:Null}">
        <Image Source="icons/excel.png" Width="30" Height="30" />
    </Hyperlink>
</TextBlock>

.........

Jemand eine Idee wie das geht?

09.10.2016 - 10:31 Uhr

Ich habe jetzt einige Varianten probiert aber keine hat zum Erfolg geführt.
Beim googlen habe ich auch ein paar Links gefunden, welche das selbe Problem haben.
Allerdings war nie wirklich eine brauchbare Lösung dabei.

Das ist aktuell mein letzter Stand.

Das dataGrid sieht aus wie davor... 😦

                                            
<Expander.Header>
<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="auto"></ColumnDefinition>
    <ColumnDefinition Width="*"></ColumnDefinition>
  </Grid.ColumnDefinitions>
                                                    
  <StackPanel Grid.Column="0" Orientation="Horizontal" Width="auto">
    <TextBlock Text="{Binding Items[0].firstname}" />
    <TextBlock Text="{Binding Items[0].lastname}" />
    <TextBlock Text="{Binding Items[0].age}" />
    <TextBlock Text="{Binding Path=ItemCount}" />
  </StackPanel>

  <StackPanel Grid.Column="1" Orientation="Horizontal" Width="auto" HorizontalAlignment="Right">
    <Button HorizontalAlignment="Right">
      <Button.Content>
        <StackPanel Orientation="Horizontal">
          <TextBlock Text="Datensatz hinzufügen: "/>
          <TextBlock Text="{Binding Name}"/>
        </StackPanel>
      </Button.Content>
     </Button>
  </StackPanel>
                                                    
</Grid>
</Expander.Header>

08.10.2016 - 17:54 Uhr

Mh ist mir irgendwie nicht ganz klar..

So funktioniert es auf jeden Fall nicht... 😃

<GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type GroupItem}">
                                        <Expander Background="#FFB4B4B4">
                                            <Expander.Header>
                                                <StackPanel Orientation="Horizontal" Width="auto">
                                                    <TextBlock Text="{Binding Items[0].firstname}" />
                                                    <TextBlock Text="{Binding Items[0].lastname}" />
                                                    <TextBlock Text="{Binding Items[0].age}" />
                                                    <TextBlock Text="{Binding Path=ItemCount}" />
                                                    <StackPanel Orientation="Horizontal" Width="auto">
                                                        <Button HorizontalAlignment="Right">
                                                            <Button.Content>
                                                                <StackPanel Orientation="Horizontal">
                                                                    <TextBlock Text="Datensatz hinzufügen: "/>
                                                                    <TextBlock Text="{Binding Name}"/>
                                                                </StackPanel>
                                                            </Button.Content>
                                                        </Button>
                                                    </StackPanel>
                                                </StackPanel>
                                            </Expander.Header>
                                            <ItemsPresenter />
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
</GroupStyle.ContainerStyle>
08.10.2016 - 11:43 Uhr

Jemand eine Idee, wie ich den Button rechts-bündig ausgerichtet bekomme?
Egal was ich probiere er bleibt immer links..