Forum: PC-Programmierung Aktualisierung einer WPF-Anwendung


von Tim G. (Gast)


Lesenswert?

Hallo,

ich bin relativ neu in der Anwendung von WPF/C#.
Bei meiner Anwendung geht es um das Auslesen via serieller 
Schnittstelle.
Mit einer Konsolenanwendung habe ich das Auslesen bereits programmiert.
Nun wollte ich die Methoden (leicht abgeändert) in mein WPF Projekt 
einfügen, sodass auf der GUI immer die geänderten Werte z.B. in einer 
Textbox angezeigt werden. Hierdrin liegt das Problem.
Ich habe keine Ahnung wie ich diese immmer wieder aktualisierten Werte 
in die Anwendung einbinden kann, bzw. dass sich die Anwendung diese 
Werte immer wieder neu holt.

Sagen wir einfach, ich drehe an einem Potentiometer und die Änderung 
wird dann an der USB-Schnittstelle rausgeschickt. Diese Änderung 
erhöht/erniedrigt einen bestimmten Wert, der nun in der Textbox 
angezeigt werden soll.

Hat jemand eine Lösung?

von Karl H. (kbuchegg)


Lesenswert?

Tim G. schrieb:

> Hat jemand eine Lösung?

Ja.
Hänge nicht an der Methode fest, die du bei einer Konsolenanwendung 
benutzt hast, sondern passe dich an die Programmierweise unter C# an. 
Alles andere ist sonst nämlich ein Kampf gegen Windmühlen.

Es gibt eine Klasse für serielle Schnittstellen. Und ein Objekt davon 
empfängt einen Event, wenn sich an der Schnittstelle etwas tut.

Google ist dein Freund. Und nein, du bist nicht der Erste, der mit C# an 
die Serielle ran will.

von Tim G. (Gast)


Lesenswert?

so schaut grad mein Programm aus. ist ein kleines großes durcheinander.
bei mir haperts jetzt nur daran, dass er zwar die methode MainWindow 
durchläuft, nur er soll danach die anderen Methoden immer wieder 
aufrufen und das bekomme ich leider nicht hin.




public partial class MainWindow : Window
    {
        SerialPort port = new SerialPort("COM1", 57600, Parity.None, 8, 
StopBits.One);

        [...]

        public MainWindow()
        {
            InitializeComponent();
            stRding();
            port.DataReceived += new 
SerialDataReceivedEventHandler(DataAnalyse);
            stpRding();
        }

        private void stRding()
        {
            port.RtsEnable = true;
            port.Encoding = Encoding.Default;
            port.Open();
        }

        private void stpRding()
        {
            port.Close();
        }

        private void DataAnalyse(object sender, 
SerialDataReceivedEventArgs e)
        {
            string rdata = port.ReadExisting().ToString();

            StringBuilder sb = new StringBuilder();

            foreach (char c in rdata)
            {
                sb.Append(Convert.ToString(c, 16));
            }

            string hex_string = sb.ToString();
            int hex_l = hex_string.Length;
            string element = "";
            string data = "";
            int el_ident = 0;

            #region Elements

            if ((hex_l > 4) && (hex_l < 7))
            {
                element = hex_string[0].ToString() + 
hex_string[1].ToString();
                if (hex_l >= 6)
                {
                    data = hex_string[5].ToString()
                         + hex_string[4].ToString()
                         + hex_string[3].ToString();
                    int i = 0;
                    string[] el_data = new string[16];
                    string[] sel_element = new string[16];

                    #region Jogwheel_right
                    el_ident = String.Compare("3f", element);
                    if (el_ident == 0)
                    {
                        switch (hex_string[hex_l - 2])
                        {
                            case '1':
                                jogwheel_right -= 1;
                                break;
                            case '3':
                                jogwheel_right += 1;
                                break;
                        }

                    }
                    sel_element[i] = "Jogwheel_rechts";
                    el_data[i] = jogwheel_right.ToString();
                    textBox7.Text = el_data[i];
                    i++;

                    #endregio

von Arc N. (arc)


Lesenswert?

Tim G. schrieb:
> Hallo,
>
> ich bin relativ neu in der Anwendung von WPF/C#.
> Bei meiner Anwendung geht es um das Auslesen via serieller
> Schnittstelle.
> Mit einer Konsolenanwendung habe ich das Auslesen bereits programmiert.
> Nun wollte ich die Methoden (leicht abgeändert) in mein WPF Projekt
> einfügen, sodass auf der GUI immer die geänderten Werte z.B. in einer
> Textbox angezeigt werden. Hierdrin liegt das Problem.
> Ich habe keine Ahnung wie ich diese immmer wieder aktualisierten Werte
> in die Anwendung einbinden kann, bzw. dass sich die Anwendung diese
> Werte immer wieder neu holt.

Entweder wie "früher" alles per Code ala myTextBox.Text = "abcdefg" oder 
per DataBinding, kleines Beispiel
1
// die Datenquelle
2
public class MyDataSource {
3
    string mString = "abcdefg";
4
    public string AProperty { 
5
        get { return mString; } 
6
        set { mString = value; } }
7
    public MyDataSource(string s) {
8
        mString = s;
9
    }
10
}
der Rest ist XAML
Binding festlegen (textBox1.Text an MyAppDataSource.AProperty, in beide 
Richtungen, autom. wenn es geändert wird)
1
<TextBox Height="50" HorizontalAlignment="Left" Margin="0,0,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" 
2
                 Text="{Binding Source={StaticResource MyAppDataSource}, Path=AProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
Jetzt fehlt noch die Verknüpfung von MyAppDataSource mit der "echten" 
(hier in App.xaml)
Es wird hier autom. eine Instanz von MyDataSource erzeugt
(im Programm geht das mit textBox1.DataContext = myDataSourceInstance)
1
<Application ...
2
    xmlns:src="clr-namespace:MyAppNamespace"
3
    xmlns:system="clr-namespace:System;assembly=mscorlib" 
4
    ... >
5
    <Application.Resources>
6
        <ObjectDataProvider x:Key="MyAppDataSource"
7
                        ObjectType="{x:Type src:MyDataSource}" />  
8
            <ObjectDataProvider.ConstructorParameters>              
9
                <system:String>Test constructor parameter</system:String>
10
            </ObjectDataProvider.ConstructorParameters> 
11
        </ObjectDataProvider>  
12
    </Application.Resources>
13
</Application>


>
> Sagen wir einfach, ich drehe an einem Potentiometer und die Änderung
> wird dann an der USB-Schnittstelle rausgeschickt. Diese Änderung
> erhöht/erniedrigt einen bestimmten Wert, der nun in der Textbox
> angezeigt werden soll.
>
> Hat jemand eine Lösung?

http://msdn.microsoft.com/en-us/library/aa480224.aspx
http://msdn.microsoft.com/en-us/library/aa480226.aspx
http://bea.stollnitz.com/blog/?p=22
http://blogs.msdn.com/wpfsdk/archive/2006/10/19/wpf-basic-data-binding-faq.aspx
http://www.codeproject.com/KB/WPF/MovingTowardWpfBinding.aspx

> so schaut grad mein Programm aus. ist ein kleines großes durcheinander.
> bei mir haperts jetzt nur daran, dass er zwar die methode MainWindow
> durchläuft, nur er soll danach die anderen Methoden immer wieder
> aufrufen und das bekomme ich leider nicht hin.

DataReceived ist ein Event, das autom. ausgelöst wird, wenn Daten 
ankommen (passendes ReceivedBytesThreshold und Encoding nicht 
vergessen).
Zudem ist hier die übliche Baustelle wieder eröffnet:
Wenn UI-Elemente aus einem anderen Thread (hier DataReceived) geändert 
werden sollen, muss dies über Invoke im UI-Thread gemacht werden
1
// im DataReceived-Handler
2
// im gleichen Thread
3
if (textBox1.Dispatcher.CheckAccess()) {
4
   textBox1.Text = "abcdefg";
5
} else {
6
   // Update wird aus einem anderen Thread gestartet
7
   textBox1.Dispatcher.Invoke(DispatcherPriority.Normal, MyUpdateDelegate);
8
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.