darkprodukt
Goto Top

TextBox mit eingabe Maske

Guten Abend,

ich versuche gerade meiner Textbox eine "Maske" zu verpassen. Ich weis es gibt auch MaskedTextBox aber diese ist leider ungeeignet.
Ich möchte das nur kleinbuchstaben ( hab ich schon mit "CharacterCasing = Lower" gemacht ), Zahlen, Komma und "Leerzeichen" akzeptiert werden.

Ich Arbeite mit Windows Forms (VS Express C++ 2010)

Hab versucht von diesem sehr gut beschriebenen Beitrag die TextBox in C++/CLI zu übertragen.
http://www.mycsharp.de/wbb2/thread.php?threadid=17535

Zwischendurch hatte ich auch andere ideen wie z.b. TextBox->Undo();... den erfolg kann man hier bewundern ;)
Error: C2065 - for each Char in Char Array

Der Fehler:
...\forms_tests2\Eigenschaften.h(17 im code): error C2664: 'System::Windows::Forms::TextBoxBase::SelectionStart::set': Konvertierung des Parameters 1 von 'System::Int32 ^' in 'int' nicht möglich
Es ist kein benutzerdefinierter Konvertierungsoperator verfügbar, oder
Es gibt keinen Kontext, in dem diese Konvertierung möglich ist
...\Eigenschaften.h(18 im code): error C2664: 'System::Windows::Forms::TextBoxBase::SelectionLength::set': Konvertierung des Parameters 1 von 'System::Int32 ^' in 'int' nicht möglich
Es ist kein benutzerdefinierter Konvertierungsoperator verfügbar, oder
Es gibt keinen Kontext, in dem diese Konvertierung möglich ist

Handle:
private: System::Void TextBox_VideoDataExtensions_TextChanged(System::Object^  sender, System::EventArgs^  e) 
{
    String^ VDEx_allowedChars = L"abcdefghijklmnopqrstuvwxyz0123456789, ";  

    if( VDEx_validating )
        return;

    try
    {
        VDEx_validating = true;

        for(int i = 0; i < TextBox_VideoDataExtensions->Text->Length; i++)
        {
            if( !VDEx_allowedChars->Contains(TextBox_VideoDataExtensions->Text->ToCharArray()[i].ToString()))
            {
                TextBox_VideoDataExtensions->Text = VDEx_lastValidText;
                TextBox_VideoDataExtensions->SelectionStart = VDEx_lastValidSelectionStart;
                TextBox_VideoDataExtensions->SelectionLength = VDEx_lastValidSelectionLength;
                return;
            }
        }
        VDEx_lastValidText = TextBox_VideoDataExtensions->Text;
        VDEx_lastValidSelectionStart = TextBox_VideoDataExtensions->SelectionStart;
        VDEx_lastValidSelectionLength = TextBox_VideoDataExtensions->SelectionLength;
        }
    finally
    {
        VDEx_validating = false;
    }
}
Definiert...
private: String^ VDEx_lastValidText;
pivate: Int32^ VDEx_lastValidSelectionStart;
private: Int32^ VDEx_lastValidSelectionLength;
private: bool^ VDEx_validating;
Im Form Load Handle
VDEx_lastValidText = TextBox_VideoDataExtensions->Text;
VDEx_lastValidSelectionStart = nullptr;
VDEx_lastValidSelectionLength = nullptr;
VDEx_validating = false;

Hat einer vieleicht noch Idee oder eine andere portable Lösung?

Vielen denk für alle Antworten!

Mit freundlichen Grüßen,

Darkprodukt

[Edit1]: Achja was vieleichtnoch wichtig ist, ist das dies ein untergeordnetes Fenster ist.
Und die TextBox_VideoDataExtensions meist schon beim aufruf von einem String gefüllt wird.

Jetzt bin ich mir nicht ganz sicher, ob dan zuerst das Form_Load event kommt oder das TextBox_VDEx_TextChange event...
Form_Load müsste aber das erste sein...

[Edit2]: Achja vieleicht noch etwas zum Endergebnis...
Ich möchte dem User eine schnittstelle geben in der dieser festlegen kann welche datein mein programm als Videodatein identifizieren soll.
Die Textbos soll dieses format haben als Eingabe: "mkv, mp4, avi" etc.
mit dieser funktion:
private: List<String^>^ StringToList(String^ imput)
{
    List<String^>^ Extensions = gcnew List<String^>;

    imput = L"." + imput->Replace(L", ", L", .");  

    while( String::IsNullOrWhiteSpace(imput) == false )
    {
        if( imput->IndexOf(L",") <= 0 )  
        {
            Extensions->Add(imput->Trim());
            imput = imput->Remove(0, imput->Trim()->Length);
        }
        else
        {
            Extensions->Add(imput->Remove(imput->IndexOf(L","))->Trim());  
            imput = imput->Remove(0, imput->Remove(imput->IndexOf(L","))->Length + 2);  
        }
    }

    return Extensions;
}

Wird das ganze dann in eine Liste von Dateiendungen verwandelt.

Content-Key: 230861

Url: https://administrator.de/contentid/230861

Printed on: April 26, 2024 at 11:04 o'clock

Member: colinardo
colinardo Feb 25, 2014 updated at 10:55:52 (UTC)
Goto Top
Hallo Darkprodukt,
also die Eingabe von ungültigen Zeichen lässt sich so in der Textbox abfangen :
Beispiel: (im Beispiel ist txt1 eine Textbox)
private: bool notValidChar;
	
	private: System::Void txt1_KeyDown(System::Object^  sender, System::Windows::Forms::KeyEventArgs^  e) {
				 notValidChar = false;
	                         if ((e->KeyValue > 64 && e->KeyValue < 91) || (e->KeyValue > 47 && e->KeyValue < 58) || e->KeyCode == Keys::Oemcomma || e->KeyCode == Keys::Space ){
						 notValidChar = false;
				 }else{
					 notValidChar = true;
				 }
				 if (Control::ModifierKeys == Keys::Shift){
					 notValidChar = true;
				 }
			 }
	private: System::Void txt1_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) {
				if (notValidChar == true){
					e->Handled = true;
				}
			 }
Eine Prüfung auf das richtige Eingabe-Format für deine Extensions würde ich mit Regex machen:
Beispiel (im Beispiel ist txt1 eine Textbox und btnCheck ein Button)
#include <regex>
#include <string>
#include <iostream>
using namespace std;
using namespace System;

       void MarshalString ( String ^ s, string& os ) {
		using namespace Runtime::InteropServices;
		const char* chars = (const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
		os = chars;
		Marshal::FreeHGlobal(IntPtr((void*)chars));
	}

	private: System::Void btnCheck_Click(System::Object^  sender, System::EventArgs^  e) {
				regex reg("([a-z0-9]{2,4}),? ?");  
				String^ txtBox = txt1->Text;
				std::string txtBox_Std;
				MarshalString(txtBox,txtBox_Std);
				std::smatch result;
				if(std::regex_search(txtBox_Std,reg)){
					while(std::regex_search(txtBox_Std, result, reg))
					{
						String^ submatch = gcnew System::String(result[1].str().c_str());
						MessageBox::Show(submatch);
						txtBox_Std = result.suffix().str();
					}
				}else{
					MessageBox::Show("No Match");  
				}
		 }
Grüße Uwe
Member: Darkprodukt
Darkprodukt Feb 25, 2014 at 21:11:53 (UTC)
Goto Top
Guten Abend colinardo,

danke für die Antwort. Die erste Lösung ist leider nicht ganz was ich mir vorgestellt habe, da es, wie auch in dem Artikel den ich gepostet habe beschrieben, ein Kampf gegen windmühlen ist. Es gibt einfach zu viele Möglichkeiten Windows zu einer eingabe zu bringen. (Kopieren, über die ASCII Tabbel [ALT] + Nummer, windows Sprachsteuerung, etc.) Es gibt einfach zu viele möglichkeiten und wenn ich diese alle Deaktivieren würde, macht dies uner umständen die bedienung meines Programms unmöglich. z.b. Kopieren...

Die zweite Lösung finde ich um einiges Interessanter, da man so z.B. das verlassen der TextBox verhinder kann, bis der user seine Eingabe korregiert hat.

Ich werd es, wenn ich heute noch Zeit finde, ausprobieren und sobald wie möglich rückmeldung geben.


Mit freundlichen Grüßen

Darkprodukt
Member: Darkprodukt
Darkprodukt Mar 29, 2014 at 13:02:40 (UTC)
Goto Top
Guten Tag,

tut mir leid das ich mich nicht schon früher gemeldet habe... leider hatte ich nicht besonders viel Zeit an meinem Privatprojekt weiter zu basteln face-sad

Ich habe mit der Lösung etwas rumgespielt und bin zu dem schluss gekommen, dass es einfach zu viele ausnahmen gibt.
Ich werde mir einfach eine Liste mit den 30 gängigsten Videodateiendungen erstellen in der der User auswählen kann, welche er möchte...


Vielen Dank für die Arbeit

Darkprodukt