Laden...
T
TBMSam myCSharp.de - Member
IT-Praktikant Friedrichshafen, Germany Dabei seit 19.09.2018 9 Beiträge
Benutzerbeschreibung

Forenbeiträge von TBMSam Ingesamt 9 Beiträge

19.04.2021 - 11:06 Uhr

Hallo Freunde 🙂

ich versuche gerade eine kleine C#Anwendung zu schreiben und habe, da ich leider nur ein kleiner, gerade anfangen habender Student bin, gehofft, dass mir vielleicht jemand mit einem Rat bzw. ein paar Tipps helfen kann, folgende Anforderung umzusetzen:

Bei Programmstart der WinForms-Anwendung (exe-Datei) wird eine Funktion aufgerufen, die auf einem entfernten Server (eine NAS - network attached storage - mit Benutzername + Passwort) unter einer bestimmten Adresse nachschaut, ob eine Aktualisierung - also ein Update - vorliegt. Wenn ja dieses herunterladen + installieren (mit entsprechender Anzeige für den Benutzer), anschließend das Programm (neuer Programmstand) wieder starten.

Durch etwas Recherche habe ich folgendes Code-Fragment gefunden, ich hoffe es hilft etwas:


var webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
webClient.DownloadFileAsync("https://195.50.139.130:5001/FTP/KlingGastro Update/file.txt", "C:\\file.txt");

Ich glaube, dass das Herunterladen von irgendwelchen Dateien nicht das Problem sein wird (habe folgendes Tutorial gefunden: https://ourcodeworld.com/articles/read/227/how-to-download-a-webfile-with-csharp-and-show-download-progress-synchronously-and-asynchronously), sondern das Abbrechen des Programms durch sich selbst und danach der Neustart.

Würde mich über jedwede Hilfe sehr sehr freuen, vielen Dank im Vorraus für sämtliche Antworten.

Liebe Grüße

19.11.2019 - 16:25 Uhr

Hallo Freunde,

Ich versuche gerade, eine simple Xamarin.Android-App zu erstellen, die eine Tabelle anzeigt. Sie zeigt nebst dem Table-Head ein ListView, der mehrere Elemente enthält.

Ist es möglich, dass bei Klick auf eines der Elemente die entsprechende Zeile als Ladebalken angezeigt wird, der gleichmäßig innerhalb eines bestimmten Zeitintervalls (bspw. 30 sec) von links nach rechts läuft?

Ich habe unten einen Screenshot angefügt, ich hoffe dieser zeigt die Tabelle etwas deutlicher, bzw., was ich zu tun versuche.

Zuletzt noch etwas Code, vielleicht hilft dieser auch ein wenig. Ich habe ihn etwas gekürzt, wenn ich zu viel rausgelöscht habe oder irgendetwas dadurch unverständlich wurde, lasst es mich wissen:

public class TableActivity : Activity
{
    ListView lv;
    ListAdapter adapter = null;
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        //...
        lv = FindViewById<ListView>(Resource.Id.geraeteListView);
        adapter = new ListAdapter(this, Resource.Layout.List, geraeteliste.CurrentGeraeteliste, Intent.GetStringExtra("ServerIP"))
        {
            parentActivity = this
        };
        lv.Adapter = adapter;
    }

    private async void OnItemClick(object sender, AdapterView.ItemClickEventArgs e)
    {
        if (geraeteliste.CurrentGeraeteliste[e.Position].bespielt == "J") return;
        //…
        await Task.Delay(0);
    } 
}

public class ListAdapter : ArrayAdapter
{
    //...
    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        View v = convertView;
        if (v == null)
        {
            LayoutInflater inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
            v = inflater.Inflate(Resource.Layout.List, parent, false);
        }
        //...
        v.FindViewById<ImageView>(Resource.Id.typeImageView).SetImageResource(Resource.Drawable.Icon);
        v.FindViewById<TextView>(Resource.Id.numberTextView).Text = Geraetelist[position].geraeteplatz;
        v.FindViewById<TextView>(Resource.Id.descriptionTextView).Text = Geraetelist[position].geraeteinformation;
        ImageView iv = v.FindViewById<ImageView>(Resource.Id.bspImageView);
        iv.SetImageResource(Geraetelist[position].bespielt == "N" ? Resource.Drawable.greenPoint : Resource.Drawable.redPoint);
        //…
        return v;        
    }
}

Wäre wirklich dankbar für jeden Hinweis / jede noch zu kleine Antwort/Hilfe.^^

Liebe Grüße 😃

04.02.2019 - 13:04 Uhr

Hallo zusammen,

mein Programm zeigt bei Ausführung einen Button sowie eine Tabelle mit 2 Spalten an. Bei Klick auf den Button möchte ich gerne einen speziellen Eintrag in dieser Tabelle ändern. Aber nur diesen einen. Alle anderen Einträge sollen so bleiben wie sie sind.

Folgendes Beispiel zur Veranschaulichung:

[Programmstart]

Name des Eintrags | Wert
---------------------+---------------
Eintrag Nummer 1 | Originalwert
Eintrag Nummer 2 | Originalwert
Eintrag Nummer 3 | Originalwert

[Button-Klick]

Name des Eintrags | Wert
---------------------+---------------
Eintrag Nummer 1 | Originalwert
Eintrag Nummer 2 | Geänderter Wert
Eintrag Nummer 3 | Originalwert

Wie kann ich das erreichen? Wie muss meine private void OnButtonClick(object sender, EventArgs e)-Funktion aussehen? Vor allem, wie kann ich auf einen speziellen Eintrag in dieser Liste zugreifen?

Um mir besser helfen zu können, poste ich nachfolgend meinen Code. Es handelt sich um eine Xamarin.Android-App, ich arbeite mit einer ListView bzw. mit einem ListAdapter : ArrayAdapter:

public class MyActivity : Activity  
{  
    List List = null;  
  
    protected override void OnCreate(Bundle bundle)  
    {  
        base.OnCreate(bundle);  
  
        SetContentView(Resource.Layout.MyActivity);  
  
        List = PopulateList();  
        var lv = FindViewById(Resource.Id.list);  
        var adapter = new ListAdapter(this, Resource.Layout.List, List);  
        lv.Adapter = adapter;  
  
        FindViewById(Resource.Id.button).Click += OnButtonClick;  
    }  
}
class ListAdapter : ArrayAdapter  
{  
    List List;  
    public ListAdapter(Context Context, int ListId, List List) : base(Context, ListId, List)  
    {  
        this.List = List;  
    }  
    public override int Count  
    {  
        get { return List.Count; }  
    }  
    public override View GetView(int position, View convertView, ViewGroup parent)  
    {  
        View v = convertView;  
        if (v == null)  
        {  
            LayoutInflater inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);  
            v = inflater.Inflate(Resource.Layout.List, parent, false);  
        }  
        v.FindViewById(Resource.Id.name).Text = List[position].Name;  
        v.FindViewById(Resource.Id.value).Text = "Originalwert";  
        return v;  
    }  
}

Unter Nutzung folgender *.axml-Dateien:

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout
xmlns:android        ="http://schemas.android.com/apk/res/android"  
android:orientation  ="vertical"  
android:layout_width ="match_parent"  
android:layout_height="match_parent">  
<Button
    android:layout_width ="match_parent"  
    android:layout_height="wrap_content"  
    android:text="Click Me"  
    android:id="@+id/button" />  
<ListView
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:id="@+id/list" />  
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>   
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"       
android:orientation="horizontal"       
android:layout_width="fill_parent"       
android:layout_height="fill_parent">          
<TextView   
        android:id="@+id/name"              
        android:layout_width="wrap_content"            
        android:layout_height="wrap_content" />  
<TextView   
        android:id="@+id/value"              
        android:layout_width="wrap_content"   
        android:layout_height="wrap_content" />  
</RelativeLayout>

Wie kann ich in der private void OnButtonClick(object sender, EventArgs e)-Funktion auf die entsprechende View zugreifen/diese Verändern?`

Wenn ich folgendes mache:

private void OnButtonClick(object sender, EventArgs e)  
{  
   FindViewById(Resource.Id.value).Text = "Geänderter Wert";  
}

ändert er den ersten Eintrag der Liste. Aber wie kann ich ausschließlich nur den zweiten ändern (siehe Beispiel)?

Würde mich wirklich sehr freuen, wenn sich jemand meiner annehmen und mir helfen / ein paar Tipps geben könnte.

Vielen Dank für alle Antworten schon mal im Voraus

Freundliche Grüße

10.01.2019 - 16:12 Uhr

Hallo zusammen,

Auf einer Aktivität meiner Xamarin.Android-App wird eine Tabelle bestehend aus mehreren Spalten (mittels eines ListAdapters realisiert) angezeigt. Diese wird OnCreate erstellt und von einer Datenbank Zeile für Zeile gefüllt. Um es sich besser vorstellen zu können, im Detail: Es wird pro Zeile je der Name einer Maschine sowie ihr Online-Status angezeigt. Für die Abfrage des Statuses habe ich eine Funktion, die bei Erreichbarkeit bzw. Verfügbarkeit einen entsprechenden Integer-Wert liefert. Aber diese Funktion wird ja nur einmal für jede Zeile aufgerufen (onCreate). Kann mir jemand eventuell einen Tipp geben, wie ich diese Funktion mehrfach zur Laufzeit aufrufen kann? Also alle 2 Sekunden oder so? Ziel ist am Ende, dass wenn sich der Status einer Maschine ändert, oder diese nicht (mehr) erreichbar ist, sich entsprechend die Statusanzeige in der Tabelle ändert, ohne die Tabelle jedes mal komplett neu aufzubauen oder gar jedes mal eine neue Aktivität zu erstellen.

Ich werde nachfolgend noch etwas Code posten, um das Verstehen vielleicht etwas zu erleichtern:

Activity:


protected override void OnCreate(Bundle bundle)  
{  
    //...  
    var lv = FindViewById<ListView>(Resource.Id.ListView);  
    lv.Adapter = new ListAdapter(this, Resource.Layout.List, list.CurrentList, Constants.ServerIP);  
}  

class ListAdapter : ArrayAdapter


public ListAdapter(Context Context, int ListId, List<Geraet> list, string serverip) : base(Context, ListId, Geraete)  
{   
    this.List = list;   
}

public override View GetView(int position, View convertView, ViewGroup parent)  
{  
    View v = convertView;  
    if (v == null)  
    {  
        LayoutInflater inflater = (LayoutInflater) Context.GetSystemService(Context.LayoutInflaterService);  
        v = inflater.Inflate(Resource.Layout.List, parent, false);  
    }
    v.FindViewById<TextView>(Resource.Id.TextView).Text = List[position].Bezeichnung; 
    if (Get_Status(List[position]) == 1)  
    {  
        v.FindViewById<ImageView>(Resource.Id.ImageView).SetImageResource(Resource.Drawable.green);  
    }  
    if (Get_Status(List[position]) != 1)  
    {  
        v.FindViewById<ImageView>(Resource.Id.ImageView).SetImageResource(Resource.Drawable.red);  
    }
    return v;  
}   

Ich habe auch schon ein paar eigene Versuche unternommen, jedoch waren diese leider nicht von Erfolg gekrönt. Ich werde trotzdem mal die verschiedenen Versuche auch noch posten, vielleicht sieht man ja direkt, woran es gescheitert ist.

1.) using System.Threading:


//(...)
var thread = new Thread(() => MethodToRun(geraet));  
thread.Start();
//(...)
void MethodToRun(Geraet geraet)  
{  
    while (true)  
    {  
        Thread.Sleep(2000);  
        var a = new Activity();  
        a.RunOnUiThread(() => {    
            int status = Get_Status(geraet);  
            if (status == 1)  
            {  
                v.FindViewById<ImageView>(Resource.Id.ImageView).SetImageResource(Resource.Drawable.green);  
            }  
            if (status != 1)  
            {  
                v.FindViewById<ImageView>(Resource.Id.ImageView).SetImageResource(Resource.Drawable.red);  
            }  
        });  
    }  
} 

Erhaltene Fehlermeldung: Java.Lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() (MethodToRun() Zeile 6)

2.) Mit einem Handler:


handler = new Handler(Looper.MainLooper);  
actions = new Runnable(() =>  
{  
    int status = Get_Geraetestatus(Geraetelist[position]);  
  
    handler.Post(() =>  
    {  
        ImageView display = v.FindViewById<ImageView>(Resource.Id.ImageView);    
        led.SetImageResource(status == 1 ? Resource.Drawable.green: Resource.Drawable.red);    
        PostAction();  
    });  
  
});
 
private void PostAction()  
{  
    handler.PostDelayed(() => {  
        new Thread(actions).Start();  
    }, 2000);  
}  

Erhaltene Fehlermeldung: Keine, jedoch wird auch nichts angezeigt. Wenn ich mit dem Debugger durchgehe, sieht es so aus, als geht er gar nicht in den Code nach Runnable actions = new Runnable() rein. Auch werden die Variablen handler sowie actions weder angelegt, noch wird ihnen ein Wert zugewiesen.

3.) ThreadWithState


ThreadWithState tws = new ThreadWithState(Serverip, Geraetelist[position]);  
Thread thread = new Thread(new ThreadStart(tws.ThreadProc));
thread.Start();

public class ThreadWithState
{
   public void ThreadProc()  
   {  
      while (true)  
      {  
        Thread.Sleep(1000);  
        Activity a = new Activity();  
        a.RunOnUiThread(() => { geraetestatus = Get_Geraetestatus(geraet); });  
      }  
   }
}   

Erhaltene Fehlermeldung: Could not convert "System.Threading.ThreadStart" to "Java.Lang.IRunnable" (new Thread()-Parameter Zeile 2) - obwohl das in meiner Anleitung (https://docs.microsoft.com/de-de/dotnet/standard/threading/creating-threads-and-passing-data-at-start-time) der fast gleiche Code ist.

4.) using System.Timers.Timer


startTimer();

public void startTimer()  
{  
    System.Timers.Timer Timer = new System.Timers.Timer();  
    Timer.Start();  
    Timer.Interval = 1000;  
    Timer.Enabled = true;  
    Timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) =>  
    {  
        RunOnUiThread(() =>  
        {  
            lv.Adapter.NotifyDataSetChanged();  
        });  
    };  
    Timer.Start();  
}  

Erhaltene Fehlermeldung: > Fehlermeldung:

"IListAdapter" enthält keine Definition für "NotifyDataSetChanged", und es wurde keine verfügbare NotifyDataSetChanged-Erweiterungsmethode gefunden, die ein erstes Argument vom Typ "IListAdapter" akzeptiert (möglicherweise fehlt eine using-Direktive oder ein Assemblyverweis). (Zeile lv.Adapter.NotifyDataSetChanged();)

Abschließend kurz noch ein paar Gedanken zur Theorie: Ich dachte evtl. an so etwas wie pro Statusanzeige 1 Thread, der in einer Endlosschleife alle Sekunde den Status holt (Stichwort: asynchron?) In der Aktivität dann sowas wie ein Listener, der auf Änderungen await[ed] (sowas wie NotifyStatusChanged(); oder so), bei Änderung dann usw. usw... irgendwie so keine Ahnung, kann auch anderst sein, ich weiß es nicht, bin leider noch ein ziemlicher Anfänger 😦

Würde mich wirklich sehr freuen, wenn sich jemand meiner annehmen und mir helfen / ein paar Tipps geben könnte.

Vielen Dank für alle Antworten schon mal im Voraus

Freundliche Grüße

12.12.2018 - 12:39 Uhr

Danke schonmal für eure Antworten.

@FZelle Oh man sorry ich Trottel hab das falsche Bild eingebunden.

Also die im Code angegebene IP ist sowohl die meines Rechners als auch die dessens, auf dem der Broadcast-Dienst läuft. Macht also keinen Unterschied.

Werde jetzt mal versuchen, ob ich den Broadcast per UdpClient empfangen kann und melde mich dann nochmals. Denke halt das der Broadcast auch per Socket verschickt wird, habe folgenden Code als Auszug eines bereits funktionieren Receivers bekommen:

        private IPEndPoint ipendpoint;
        private Socket socket;
        private byte[] broadcastdata = null;

        sealed protected override async Task<AsyncTaskState> DoInitialize()
        {
            var result = AsyncTaskState.CancelTask;

            try
            {
                socket = new Socket(AddressFamily, SocketType, ProtocolType)
                {
                    ReceiveBufferSize = 100 * TaskSettings.Length
                };
                socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, TaskSettings.TimeOut);
                ipendpoint = new IPEndPoint(TaskSettings.IPAddress, TaskSettings.Port);
                socket.Bind(ipendpoint);

                result = AsyncTaskState.NoError;
            }
            catch
            {
                result = AsyncTaskState.CancelTask;
            }

            if (result == AsyncTaskState.NoError) broadcastdata = new byte[TaskSettings.Length];

            return await CancellationRequest(result);
        }


        sealed protected override async Task<AsyncTaskState> DoExecute()
        {
            if (socket.Available <= 0) return await CancellationRequest(AsyncTaskState.NoResult);

            var result = AsyncTaskState.NoResult;

            try
            {
                var ep = (EndPoint)ipendpoint;
                var received = socket.ReceiveFrom(broadcastdata, ref ep);
                result = ((received == TaskSettings.Length) && (InternalDetect(broadcastdata))
                    ? AsyncTaskState.HandleResult
                    : AsyncTaskState.NoResult);

                if (result == AsyncTaskState.HandleResult)
                {
                    TaskResult.Available = socket.Available;
                    TaskResult.BroadcastData = broadcastdata;
                    TaskResult.IPAddress = ((IPEndPoint)ep).Address.ToString();
                }
            }
            catch
            {
                result = AsyncTaskState.NoResult;
            }

            return await CancellationRequest(result);
        }

12.12.2018 - 11:49 Uhr

Hallo zusammen,

Ein Server in meinem lokalen Netz sendet alle 5 Sekunden einen 120 Byte langen UDP-Broadcast.

Daher versuche ich nun, einen Sockel aufzusetzen, um diesen Broadcast abzufangen und auszuwerten:


IPAddress ip = IPAddress.Parse("192.168.127.162");
IPEndPoint ipe = new IPEndPoint(ip, 55555);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
{
    ReceiveBufferSize = 120 
};
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 30);
socket.Bind(ipe);

Meine lokalen cmd -> /ipconfig-Einstellungen sind folgendermaßen:

Bild entfernt, siehe unten - Coffeebean

Leider wirft er mir in der Zeile "socket.Bind(ipe);" folgende Exception:

Fehlermeldung:
System.Net.Sockets.SocketException: The requested address is not valid in this context

Kann sich irgendjemand erklären was das Problem sein könnte? Oder mir helfen, wie ich diesen Broadcast abfangen kann?

Wäre wirklich sehr verbunden.

Beste Grüße

26.10.2018 - 14:44 Uhr

Vielen Dank für die schnelle Antwort.

Blöd gefragt, aber wie mach ich das? Sorry, bin absoulter Anfänger, was Programmierung angeht 😦

26.10.2018 - 14:40 Uhr

Hallo zusammen.

Ich versuche, Daten von einem externen MS-SQL-Server auf einer App darzustellen (Xamarin.Android). Dazu habe ich im .xaml-File folgenden ListView eingefügt:

<ListView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/listView3" />

Die Aktivität hierzu sieht folgendermaßen aus:

protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.layout1);

        var lv = FindViewById<ListView>(Resource.Id.listView3);

        lv.Adapter = new ArrayAdapter<Item>(this, Android.Resource.Layout.SimpleListItem1, Android.Resource.Id.Text1, BaseData.GetEmployees());
        lv.ItemClick += OnItemClick;
    }

    void OnItemClick(object sender, AdapterView.ItemClickEventArgs e)
    {
        int position = e.Position; // e.Position is the position in the list of the item the user touched

        var intent = new Intent(this, typeof(DetailsActivity));

        intent.PutExtra("ItemPosition", position);

        StartActivity(intent);
    }

und die get-Methode:

public static List<String> GetEmployees()
    {
        List<String> list = new List<String>();

        string sql = "SELECT adrsuche1 FROM adressen";

        using (SqlConnection con = new SqlConnection(connectionString))
        {
            con.Open();

            using (SqlCommand cmd = new SqlCommand(sql, con))
            {
                using (SqlDataReader reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        list.Add(reader.GetString(0));
                    }
                }
            }

            con.Close();

            return list;
        }
    }

Die Spalte in der Datenbank, die mit dem SQL-Befehl anzusprechen versucht wird, enthält einfache strings.

Leider unterringelt er mir BaseData.GetEmployees() (Activity Zeile 8 ) und ich erhalte folgende Fehlermeldung:

Fehlermeldung:
Konvertierung von "System.Collections.Generic.List<string>" in "GroceryList.Item[]" nicht möglich.

Kann mir jemand vielleicht sagen, was das Problem ist und wie ich das lösen kann, sodass die Daten von der Datenbank korrekt angezeigt werden?

Vielen Dank schonmal,

Beste Grüße

19.09.2018 - 15:46 Uhr

Hallo zusammen,

ich bin leider neu im Thema der App-Programmierung. Für meinen Arbeitgeber muss ich im Selbststudium eine spezielle Android-App vollständig erstellen und programmieren.

Ich bin bisher soweit gekommen, dass ich bereits so eine Art "Login"-Seite habe, aber jetzt muss ich Daten von einem Microsoft SQL-Server lesen und irgendwie in der App angezeigt bekommen.
Später müssten natürlich in dem Login-Formular die Benutzerdaten mit der Datenbank abgeglichen werden, doch das ist ein späterer Schritt.

Wie ist das möglich?

Ich habe folgende Arbeitsvorraussetzungen:
*Microsoft Visual Studio 2017 *Microsoft SQL Server 2012

Ich stelle mal noch zusätzlich etwas Code ein, damit es hoffentlich vllt etwas leichter ist, mir zu helfen.

MainPage.xaml

<ContentPage.Content>
    <StackLayout>

        <Label Text="You are here:" HorizontalOptions="Center" />
        <Label Text="[dbname].[dbo].[Adressen].adrsuche1" HorizontalOptions="Center" />

    <!--<Label Text="Later some data from the sql server should be displayed here too" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />-->

        </StackLayout>
    </ContentPage.Content>
</ContentPage>

SQLQuery.sql

SELECT adrsuche1 FROM Adressen

Vielen Dank im Vorraus schonmal für die Hilfe!