Laden...

Forenbeiträge von Quaneu Ingesamt 692 Beiträge

02.02.2015 - 12:38 Uhr

Hallo herbivore,

danke für Deine schnelle Antwort. Die Collection ist immer leer. Außerdem dachte ich, dass diese nur die Vererbten Typen beinhaltet.
Im Notfall kann ich den Namen auch selber zusammenbauen. Ich hatte gehofft, dass es da vielleicht schon was gibt 😃.

Schöne Grüße
Quaneu

30.01.2015 - 12:52 Uhr

Hallo zusammen,

ich baue gerade einen Xsd-Parser und benutze dazu CodeDom. Nun würde ich gern NestedClasses erzeugen. Dies ist auch kein Problem, jedoch würde ich gerne den "vollen" Namen der Klasse wissen.
Z.B.


internal class A
{
   internal class B
   {   }
}

Ich habe von B nun eine CodeTypeDeclaration und würde gerne folgenden Namen bekommen A.B. Jedoch steht im Namen nur B. Gibt es eine Möglichkeit an den vollen Namen zu gelangen und wenn welche?

Schöne Grüße
Quaneu

10.12.2014 - 15:54 Uhr

Ich habe den Fehler endlich behoben. In der Column darf man die Itemes wohl nicht befüllen.

So sieht nun meine Methode zum Befüllen aus:


public void FillResults(ResultDto[] results)
{
    _resultsDataGrid.SuspendLayout();
    _resultsDataGrid.Rows.Clear();

    foreach (ResultDtoresult in results)
    {
        DataGridViewRow row = new DataGridViewRow { Tag = result };
        row.Cells.Add(new DataGridViewTextBoxCell { Value = result.Name, ValueType = typeof(String) });
        DataGridViewComboBoxCell comboBox = new DataGridViewComboBoxCell();
		foreach (String gender in result.PossibleGenera)
		{
			comboBox.Items.Add(gender);
		}
		comboBox.Value = result.Gender;
		row.Cells.Add(comboBox);
		_resultsDataGrid.Rows.Add(row);
    }

    _resultsDataGrid.Sort(_nameColumn, ListSortDirection.Ascending);
    _resultsDataGrid.ResumeLayout();
}

10.12.2014 - 12:52 Uhr

Hallo zusammen,

ich probiere seid 3 Stunden ein Item in der DataGridViewComboBoxCell zu selektieren, aber es will einfach nicht funktionieren.

Mein Code zum befüllen des DataGrids:


public void FillResults(ResultDto[] results)
{
	_resultsDataGrid.SuspendLayout();
	_resultsDataGrid.Rows.Clear();

	foreach (ResultDtoresult in results)
	{
		DataGridViewRow row = new DataGridViewRow { Tag = result };
		row.Cells.Add(new DataGridViewTextBoxCell { Value = result.Name, ValueType = typeof(String) });
		row.Cells.Add(new DataGridViewComboBoxCell { Value = result.Gender});
		_resultsDataGrid.Rows.Add(row);
	}

	_resultsDataGrid.Sort(_nameColumn, ListSortDirection.Ascending);
	_resultsDataGrid.ResumeLayout();
}

Das DataGrid habe ich im Designer erstellt und im Code Setze ich noch die Items in der GenderColumn:


foreach (String gender in genera)
{
	_genderColumn.Items.Add(gender );
}

Wenn ich dies so mache, bekomme ich immer folgende Fehlermeldung vom Grid:> Fehlermeldung:

DataGridViewComboBoxCell value is not valid.

Wenn ich das Value nicht setzte klappt es und in der ComboBox sind auch Einträge, aber eben nur keiner Ausgewählt.

Was muss man machen, damit er ein Item selektiert, wenn ich eine Zeile hinzufüge?

Schöne Grüß
Quaneu

28.11.2014 - 14:58 Uhr

Ahhhhh... ich hab den Fehler endlich gefunden. Ich habe ein using Block für meinen Controller, der die View hält und steuert. Dies klappt natürlich wunderbar mit ShowDialog(), mit Show() läuft er natürlich weiter und räumt den Controller auf und die View...

Beispiel:


if (Communicator.Instance.TryOpenModule(1))
{
	Window moduleView = new Window();
	using (ModuleController moduleController = new ModuleController(moduleView))
	{
		moduleController.DisplayNonModal();
	}
}

D.h. wenn ich es nun wirklich nicht modal haben will, muss ich ein Event abonnieren, ob das Fenster geschlossen wurde und dann aufräumen? Bzw. ist dies der saubere Weg?

Schöne Grüße
Quaneu

28.11.2014 - 14:05 Uhr

Vielen Dank schon mal für Deine Bemühungen. Ich werde versuchen ein kleines Projekt zu erstellen, soweit es mir möglich ist.

Schöne Grüße
Quaneu

28.11.2014 - 11:34 Uhr

Hallo zusammen,

ich habe folgendes Problem und finde nicht die Ursache:

Ich habe ein Fenster A, dieses ist modal. Nun kann man in diesem auf ein TreeItem doppelt klicken und es soll ein neues Fenster B aufgehen. Diese soll nicht modal sein.
Man sieht das Fenster ganz kurz aufgehen und dann schließt es sich wieder (ohne in das Closing Event zu laufen). Wenn B modal angezeigt wird, klappt es.

Ich weiß einfach nicht wo ich den Fehler suchen soll. Nach dem Aufruf von Show() passiert nicht mehr...

Nachtrag:
Anscheinend existiert das Fenster B noch, d.h. es wird nur nicht angezeigt, obwohl Visible == true und WindowState == FormWindowState.Maximized ist.

Schöne Grüße
Quaneu

20.11.2014 - 08:14 Uhr

verwendetes Datenbanksystem: XML

Hallo zusammen,

ich versuche mich gerade an einem XML SchemaParser.

Bisher habe ich folgendes angenommen:
Complex- und SimpleTyes sind Klassen (Enums bilde ich auch über Klassen ab). Groups und AttributeGroups sind Interfaces, die die Klassen implementieren.

Doch nun sind mir zwei Dinge unklar.
Was würde es bedeuten wenn ein ComplexType eine Group beinhaltet mit naxoccures > 1?
Wenn eine Group A eine Group B beinhaltet, hat dann das Interface A ein Property vom Typ B, oder implementiert A B?

Schöne Grüße
Quaneu

P.S.
Kennt jemand ein Tool das aus einem Schema eine Beispiel XML generiert?

25.09.2014 - 11:00 Uhr

Hallo BitHai,

ich glaube der Fehler liegt in

new PropertyMetadata(false)

da dein DependencyProperty anscheinend vom Type string sein soll. Daher müsste es z.B.

new PropertyMetadata(String.Empty)

heißen.

Schöne Grüße
Quaneu

11.09.2014 - 08:45 Uhr

Ich habe gestern noch einen interessanten Artikel gefunden. Doch leider übersteigt der Code meine zwei Wochen alten C++ Kenntnisse bei weitem...

Deliver The Power Of Spy++ To Windows Forms With Our New Tool

Soweit ich gesehen habe scheint er aber auch Reflection einzusetzen, doch leider ist dies auch nur eine Vermutung.

Jetzt werde ich mir aber UI Automation Library genauer anschauen, da diese sehr vielversprechend aussieht.

10.09.2014 - 18:59 Uhr

Vielen Dank für eure Hilfe.

@FZelle:
Werd ich mir jetzt dann gleich anschauen.

@Programmierhans:
Das Problem liegt darin, die Textbox zu finden. Den Text setzten sollte dann kein Problem mehr sein.

@herbivore:
Mein Ziel ist es einen laufenden Prozess zu analysieren/modifizieren. Mit Reflection wüsste ich gar nicht wo ich anfangen soll. Brauch ja einen Type...
Snoop kann ja auch einen laufende WPF Anwendung und ich glaub sogar Forms Anwendung analysieren. Daher sollte es einen Weg geben 😃

Finde das Thema so interessant, daher würd ich sowas mal gern selbst machen.

10.09.2014 - 14:57 Uhr

Hallo zusammen,

ich schreibe gerade ein kleines Tool, mit dem ich z.B. eine TextBox in einem anderen Prozess analysieren und auch modifizieren will (Text ändern).

Beispiel:
Ich weiß, dass die TextBox den Namen "_shortNameTextBox" hat. Nun will ich über diesen Namen die TextBox in dem Prozess finden und dann z.B. "Hallo Welt" in diese schreiben.
Wie ich an das Fenster bzw. das Fensterhandle komme weiß ich schon und sehr wahrscheinlich auch wie ich den Text setzte (SendMessage(...)), doch leider finde ich keinen Weg die TextBox über ihren Namen zu finden. Über pInvoke geht dies leider nicht. Doch andere Tools können dies auch z.B. Ranorex.

Mich würde daher interessieren wie man dieses Problem lösen kann. Der Name der TextBox soll dabei nur ein Beispiel sein.

Hat jemand hierzu eine Idee?

Schöne Grüße
Quanue

16.07.2014 - 12:55 Uhr

So jetzt habe ich ein halbwegs vernünftige Lösung 😃.

Ich measure jetzt wirklich nur so viele Elemente wie nötig, bzw. werden es wohl immer bisschen mehr sein. Jedoch besser alle alle.

15.07.2014 - 10:58 Uhr

Noch nicht. Ich werd es mir heut mal anschauen.

Und vielen Dank für eure Hile 😃.

14.07.2014 - 14:56 Uhr

Ja leider. Und danach richtet sich ja dann auch die Spaltenbreite und Zeilenhöhe... Also nach dem größten Eintrag in der Zeile bzw. Spalte...
Ich muss es wohl leider wirklich so machen machen, dass die Spaltenbreite und Zeilenhöhe sich nach dem sichtbaren Eintrag in der Matrix richtet. Somit muss ich nur einen Bruchteil berechnen. Wobei das auch nicht so leicht wird... Wenn man nun aber scrollt, kann es sein das die Matrix das springen anfängt, was ich nicht sehr schön finde...

14.07.2014 - 14:27 Uhr

Also ich benutzt ein Grid als "Untersatz" und füge so viele Spalten und Zeilen hinzu, wie ich bräuchte. Das Problem liegt in dem Wort "bräuchte".Und beim selber zeichnen muss ich auch wissen wie groß jedes Element wird um nicht zu viele zu zeichnen bzw. nur diese, die auf den Bildschirm passen.

Daher stehe ich jetzt auf dem Schlauch...

14.07.2014 - 10:44 Uhr

Hallo herbivore,

also ich will Daten visualisieren um genau zu zu sein Zusammenhänge zwischen Daten anzeigen, z.B.
A -- Info --> B (A schickt nach B Info).
Dies will ich in einer Matrix anzeigen:

   A     B   
A Info
B

Leider können es sehr viele Daten sein, z.B. 300 => Matrix mit 300 * 300 Einträgen = 90000 Elemente.

Mein Ansatz ist deshalb auch nicht alle zu zeichnen sondern nur die, die angezeigt werden können. Daher musste ich aber alle Elemente "fragen" wie groß sie sind. Dies dauert natürlich zu lange.
Man könnte auch nur so viele Elemente "fragen", wie wirklich nötig sind. Doch dann würde das scrollen sehr unruhig werden, da jede Zelle in der Matrix unterschiedlich groß ist.

Ich weiß nun leider auch nicht mehr was der bessere Weg, bzw. ob es nicht einen ganz anderen gibt.

Schöne Grüße
Quaneu

03.07.2014 - 14:55 Uhr

Also ich mache das so. Der Nachteil ist, man hat ein bisschen "Code behind"...

Das Model:


public event EventHandler ShowWindowEvent;

#region Commands
public RelayCommand ShowWindowCommand { get; private set; }
#endregion

#region Command Methods
private void ShowWindow(Object parameter)
{
   OnShowWindow();
}
#endregion

private void OnShowWindow()
{
	EventHandler handler = this.ShowWindowEvent;
	if (handler != null)
	{
		handler(this, EventArgs.Empty);
	}
}

In der View das Event abonieren und


private void _model_ShowWindow(Object sender, EventArgs e)
{
    // Hier das Fentser anzeigen. Wenn Du das Model für das neue Fenster mit in die EventArgs packst, könntest Du diesen hier benutzen
}

Ist wohl nicht der sauberste Weg... lasse mich aber gern belehren 😃.

Schöne Grüße
Quaneu

02.07.2014 - 16:20 Uhr

Deine View hat doch das ViewModel als DataContext. Somit könntest Du doch in der View das Event deines ViewModels abonnieren und darauf hören. Somit muss deine View das ViewModel nicht kennen.

02.07.2014 - 15:53 Uhr

Hi,

also ich mache das auch so, bzw. ähnlich. Ich löse im Command ein Event aus, auf das die GUI z.B. dein MainWindow hört und beim auslösen das Fenster anlegt und anzeigt.
Denn sonst müsste ja ein Model eine view anlegen... Dies gefällt mir persönlich nicht.

Schöne Grüße
Quaneu

02.07.2014 - 09:38 Uhr

Hallo,

ich habe ein neues Problem bzw. Frage.

Ich habe eine UI in der sehr sehr viele UIElemente existieren können, sie werden zwar nicht alle angezeigt, aber das Measure und Arrange muss über alle UIElemente laufen.
=> Es dauert "ewig"

Ich finde einfach keinen Weg, wie man diese Vorgänge parallelisieren kann. Z.B. das in Measure nicht in einer Schleife über 100000 UIElemente iteriert wird sondern in 5 Threads über jeweils 20000. Habe dies über die TLP und Parallel versucht jedoch bekomme ich den Fehler mit dem STAThread.
Ich habe schon Möglichkeiten gefunden Fenster in verschiedenen Threads laufen zu lassen, aber noch keine Möglichkeit in einem Fenster UI-Operationen zu parallelisieren.

Daher meine Frage, gibt es eine Lösung für dieses Problem? Oder hat jemand sogar einen Ratschlag, wie man dieses Problem lösen kann

Schöne Grüße
Quaneu

01.07.2014 - 16:12 Uhr

@Abt:
Beide Wege benutzten Bindings und sind doch daher bestens geeignet für MVVM. Oder?

01.07.2014 - 15:55 Uhr

Also mir Fallen auf die schnelle zwei Möglichkeiten ein:1. Du löst es über IsSelected und dein Model reagiert drauf und setzt dementsprechend ein Property auf das die GUI "schaut" und reagiert dementsprechend.
2. Du benutzt ein ContentPresenter und bindest Dich an den TreeView (SelectedItem hier geht es 😃). Hier kannst Du dann über DataTemplates oder über ein Converter die Daten in der gewünschten Form anzeigen

01.07.2014 - 14:40 Uhr

Hallo adm1n,

leider geht das nicht ganz so einfach wie in Forms. Jedes TreeViewItem hat ein Property IsSelected und über dies kannst Du raus finden welches bzw. welche Items selektiert sind. Beim DataGrid muss man es z.B. genau so machen.


<TreeView ItemsSource="{Binding Nodes}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

Hier ist z.B. ein Artikel: wpf-mvvm-treeview-selecteditem

Schöne Grüße
Quaneu

01.07.2014 - 11:43 Uhr

Wie Du siehst ist mein 2. Punkt die Ursache für das Problem.> Fehlermeldung:

System.Windows.Data Error: 23 : Cannot convert 'ViewModel.pViewModel' from type 'pViewModel' to type 'dModel.Patient' for 'en-US' culture with default conversions; consider using Converter property of Binding.

Entweder das Property SelectedPatient bekommt den selben Typen wie die Liste. Oder Du schaltest einen Converter dazwischen (IValueConverter), der die Typen ineinander umwandelt.
Also ich würde SelectedPatient den Typ pViewModel geben, dann sollte es gehen und ich finde so wäre es auch sauber.

01.07.2014 - 11:15 Uhr

Hi Madleen,

zwei Fragen:

  1. Steht im Output Fenster etwas, wenn Du eine Zeile anklickst?
  2. Deine Liste Patients hat einen anderen Typ wie das Property SelectedPatient, ist das gewollt? Vielleicht liegt hier der Fehler.

Schöne Grüße
Quaneu

27.06.2014 - 12:43 Uhr

Also die TextBox müsste dann ReadOnly oder Disabled sein, damit der Buchstabe oder Ziffer die man gedrückt hat nicht in die TextBox geschrieben wird. Soweit ich es verstanden habe ist dies so gewünscht.
Ist die TextBox aber ReadOnly oder Disabled wird auch nie TextChanged von der GUI aus ausgelöst...
Daher muss sie nicht Readonly und Enabled sein, um über das Binding eine Änderung zu erfahren. Um nun den Buchstabe oder die Ziffer aus der TextBox zu entfernen muss man eine Art Undo machen. Dies über den Setter zu machen, denke ich, ist nicht sehr gut...

27.06.2014 - 12:01 Uhr

@Coffeebean:

Im Setter kannst du dann auch den Text wieder zurücksetzen.

Also ich bin nicht sicher ob das so geht...
Das Binding muss TwoWay sein, damit die TextBox sich aktualisiert. Daher muss er im Setter das Property setzten nicht das backing field, was dazuführt, dass er wieder in den Setter kommt usw...

Schöne Grüße
Quanue

25.06.2014 - 19:38 Uhr

@LatinChriz:
Ja es geht sehr stark in diese Richtung. Im Grunde ist es ein VirtualizingCanvas, das ein bisschen anders arbeiten würde.

Ich wollte nur sicher gehen, ob das auch der saubere Weg ist. Da es mir anfangs komisch vorkam, Elemente hinzufügen um Größe zu berechnen, dann wieder entfernen usw...

Aber anscheinend ist es der einzige und wohl auch richtige Weg.

25.06.2014 - 18:41 Uhr

Danke für deine eindringlichen Hinweise 😉. Ich kenn das Problem mit Events und benutzte sie sehr behutsam.

Ich glaub wir fangen nochmal bei 0 an. Das mit dem Fenster sollte ein Beispiel sein.

Also:

Ich habe MyCustomControl, dass ein CustomControl ist und von Control ableitet. Dieses Control verlangt ein Canvas im ControlTemplate.


[TemplatePart(Name = "PART_Canvas", Type = typeof(Canvas))]

In diesem Canvas will ich nun sehr sehr viele Elemente anzeigen lassen. Wenn ich sie alle zeichnen würde, würde es erstens lange dauern und das scrollen wäre auch nicht wirklich "schön". Daher will ich IMMER nur die Elemente dem Canvas hinzufügen und zeichnen, die in das Canvas passen. MyCustomControl hat ein Dependency Property an welches man sich binden kann, um so alle Items (noch keine UIElements) übergeben kann.
Wenn sich nun das Property ändert, oder die Größe des Canvas ändert, so muss ich die Größe aller Elemente (Children) berechnen, um zu bestimmen, welche nun wirklich dem Canvas hinzugefügt werden dürfen und welche eben nicht.
=> Mein Ziel ist es, dem Canvas nur soviele Children hinzuzufügen wie nötig.

Beispiel:
Ich habe 3456 Items die angezeigt werden sollen, aber es passen nur 30 in das Canvas, dann hat das Canvas nur 30 Children und der Rest "wartet" bis sie in den sichtbaren Bereich kommen.

Schöne Grüße
Qauneu

25.06.2014 - 16:19 Uhr

???
Das Fenster ist mein CustomControl in diesem Beispiel und über SizeChanged() bekomme ich die Änderung mit. Wenn dieses Event gefeuert wird, "berechne" ich die Größe der Elemente neu. Wenn ich nun feststelle, das z.B. Elemente hinzugefügt werden können, dann füge ich diese hinzu. Die Virtualisierung will ich immer, da in der Matrix sehr sehr viele Elemente angezeigt werden können, 10000 wäre keine Ausnahme.

25.06.2014 - 13:36 Uhr

Danke für Deine Geduld 😃

Mit Deinem Beispiel verstehe ich es auch aber für meinen Fall denke ich, dass ich es nicht anwenden kann.

Nehmen wir an, ich habe eine Liste mit n Elementen (ganz beliebige). Diese sollen in einer ListBox angezeigt werden. Dann würde ich es genau so machen wie Du.
ABER:
Die ListBox soll immer so hoch wie das Fenster sein und nur so viele Elemente zeichnen wie dargestellt werden können. D.h. doch ich muss wissen wie hoch jedes Element ist

=> Ich muss auf den Elementen folgendes aufrufen


listview.Children.Add(rowControl);
rowControl.ApplyTemplate();
rowControl.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));

Danach kann ich über die DesiredSize abfragen wie hoch das Element ist und somit weiß ich wie viele ich der ListView wirklich hinzufügen kann. Die anderen muss ich wieder entfernen, bevor die ListBox gezeichnet wird. Wie soll ich sonst herausfinden, wieviele von den n Elementen ich anzeigen soll? Das meinte ich mit "Virtualisierung" 😃.

Schöne Grüße
Quaneu

23.06.2014 - 21:00 Uhr

So jetzt muss ich leider nochmal fragen 😃

Soweit ich das erkenne, befüllst du aus der MatrixInfo-Klasse die Child-Collection, in dem du dort für eine Daten-Implementierung einen fest vergibst. Dadurch verhinderst du aber dass du eigene DataTemplates verwenden kannst. So bist du darauf angewiesen immer wieder dein Custom-Control anzupassen wenn du eine Erweiterung machen möchtest.

Ich muss dies leider machen, da ich sonst die Größe der Controls nicht ermitteln. Diese brach ich jedoch um zu ermitteln, ob sie noch gezeichnet werden sollen:


private static void MatrixChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
       ...

	foreach (RowItem rowItem in matrixInfo.RowItems.OrderBy(x => x.Index))
	{
		RowControl rowControl = new RowControl(rowItem);
		grid.Children.Add(rowControl);
		rowControl.ApplyTemplate();
		rowControl.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
	}

       ...

Oder verstehe ich Dich nicht ganz? Sorry...

Grüße
Quaneu

23.06.2014 - 16:00 Uhr

Hallo Parso,

vielen Dank für Deine Tipps und Hinweise.
Das mit den DataTemplates gefällt mir sehr gut und ich werde versuchen, dies so umzusetzen.

Für das MatrixControl habe ich ein ControlTemplate, da dies ja ein eigenes Steuerelement werden soll.

Schöne Grüße
Quaneu

23.06.2014 - 09:49 Uhr

Hmmm...

Hätte noch zwei Vorschläge:

  1. CollectionView hat ein Property CurrentItem. Wenn man sich an das bindet?
  2. Vielleicht klappt es mit IsSynchronizedWithCurrentItem="True" auch mit SelectedItem

Leider sind dies nur sehr wage Vorschläge.

Schöne Grüße
Quaneu

22.06.2014 - 21:12 Uhr

Hallo Rioma,

hab mit ListView noch nicht gearbeitet, aber klappt das nicht?


 <TextBox Text="{Binding ElementName=ListSongs, Path="{SelectedItem.Eigenschaft}"/>

Schöne Grüße
Quaneu

22.06.2014 - 15:58 Uhr

Hallo sth_Weird,

vielleicht hilft's:

Für den Konstruktoraufruf von Uri:


public Uri(string uriString)

Dieser Konstruktor erstellt eine Uri-Instanz aus einer URI-Zeichenfolge. Er analysiert den URI, bringt ihn in kanonische Form und nimmt die erforderlichen Escapecodierungen vor.

Dieser Konstruktor stellt nicht sicher, dass der Uri auf eine Ressource verweist, auf die zugegriffen werden kann.

Dieser Konstruktor geht davon aus, dass der string-Parameter auf einen absoluten URI verweist und einem Aufruf des Uri-Konstruktors entspricht, wobei UriKind auf Absolute festgelegt ist. Wenn der an den Konstruktor übergebene string-Parameter einen relativen URI darstellt, löst dieser Konstruktor UriFormatException aus.

Probier mal:

public Uri( string uriString, UriKind uriKind)

Schöne Grüße
Quaneu

22.06.2014 - 14:15 Uhr

Danke für Deine schnelle Antwort.

Leider stehe ich immer noch auf dem Schlauch...


private const FrameworkPropertyMetadataOptions metadata =
    FrameworkPropertyMetadataOptions.AffectsMeasure |
    FrameworkPropertyMetadataOptions.AffectsArrange;

// Dependency Property
public static readonly DependencyProperty MatrixProperty =
        DependencyProperty.Register("Matrix",
        typeof(MatrixInfo),
        typeof(MatrixControl),
        new FrameworkPropertyMetadata(null, metadata, MatrixChanged));

// .NET Property wrapper
public MatrixInfo Matrix
{
    get { return (MatrixInfo)GetValue(MatrixProperty); }
    set { SetValue(MatrixProperty, value); }
}

private static void MatrixChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    MatrixControl matrixControl = sender as MatrixControl;
    Canvas canvas = matrixControl._canvas;
    MatrixInfo matrixInfo = e.NewValue as MatrixInfo;

    foreach (RowItem rowItem in matrixInfo.RowItems)
    {
        RowControl rowControl = new RowControl(rowItem);
        canvas.Children.Add(rowControl);
    }

    foreach (ColumnItem columnItem in matrixInfo.ColumnItems)
    {
        ColumnControl columnControl = new ColumnControl(columnItem);
        canvas.Children.Add(columnControl);
    }

    foreach (ContentItem contentItem in matrixInfo.ContentItems)
    {
        ContentControl contentControl = new ContentControl(contentItem);
        canvas.Children.Add(contentControl);
    }
}

Hier lege meine Controls an und füge sie dem Canvas hinzu. Nun will ich die beiden Methoden verwenden.


protected override Size ArrangeOverride(Size arrangeBounds)
{
    return base.ArrangeOverride(arrangeBounds);
}

protected override Size MeasureOverride(Size constraint)
{
    return base.MeasureOverride(constraint);
}

Doch leider wird erst nach ArrangeOverride() die OnApplyTemplate() der Controls aufgerufen. Diese muss jedoch schon vor dem Aufruf von MeasureOverride() aufgerufen werde, da diese sonst nicht richtig funktioniert...

Wo liegt mein Fehler?

Schöne Grüße
Quaneu

22.06.2014 - 11:15 Uhr

Hallo zusammen,

ich will ein eigenes Control bauen, indem die Elemente zur Laufzeit hinzugefügt werden und bei zu vielen Elementen virtualisiert. D.h. Ich binde mich an eine Liste mit n Elementen und es werden z.B. n TextBoxen geniert und dem Control hinzugefügt. Wenn nun aber nur m angezeigt werden können (m<n) so sollen auch nur m gezeichnet werden.

Ich habe mir schon einige Gedanken gemacht, und habe nun einen Favoriten, doch weiß ich nicht ob diese "richtig" ist.

Ich würde es gerne über MeasureOverride() und ArrangeOverride() lösen. Doch leider scheint dies nicht ohne weiteres zu gehen, bzw. stellt sich mir hier eine Performance frage.
Bei MeasureOverride() ruft man unter anderem Measure() auf allen Kindern auf. Doch diese müssen erst hinzugefügt werden und auf allen ApplyTemplate() aufgerufen werden. Danach liefert mir DesiredSize die richtige Größe zurück, mit der ich nun die Elemente bestimmen kann, die wirklich gezeichnet werden sollen... D.h. ich muss die Elemente die nicht gezeichnet werden sollen wieder entfernen... All das erscheint mir nicht sauber... Daher auch mein Frage...

Über Tipps wäre ich sehr dankbar.

Schöne Grüße
Quaneu

10.06.2014 - 11:13 Uhr

Danke für die Antwort.

Muss nicht static sein, da die klasse aber nur diese Methode anbietet, dachte ich mir kann ich sie gleich static machen. Somit muss ich bei jedem Aufruf nicht eine Instanz anlegen.

Die Logik ist nicht in einem Fenster. Der Code ist in einem Controller, der das Fenster steuert. Und diesen Controller benutze ich für jede Operation die länger dauern könnte.
Und somit ist es doch im Grunde das, was Du geschrieben hast.

  1. Der Controller zeigt das Fenster an
  2. Der Controller führt die Operation aus
  3. Der Controller schließt das Fenster.

Schöne Grüße
Quaneu

10.06.2014 - 10:46 Uhr

Hallo zusammen,

ich habe folgendes Problem:

Für zeitintensive Operation zeige ich ein Fenster mit einem ProgressBar an. Wenn ich z.B. im Fenster A ein Objekt öffnen will geht das Prgressfenster auf, solange die Daten aus den DB geholt werden und bearbeitet werden. Danach soll das Fenster B aufgehen und die Daten anzeigen.

Diese habe ich mit Tasks gelöst:


public static void ShowProgress<TReturn>(String progressText, Object argument, Func<Object, TReturn> doAsync, Action<TReturn> callback, IWin32Window parent = null)
{
	ProgressView progressView = new ProgressView();
	TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
	TaskFactory factory = new TaskFactory(TaskScheduler.Default);
	Action<Task<TReturn>> continueCallback = new Action<Task<TReturn>>((Task<TReturn> task) =>
	{
		progressView.Close();
		callback(task.Result);
	});
	factory.StartNew(doAsync, argument).ContinueWith(continueCallback, scheduler);
	progressView.ShowProgress(progressText, parent);
}

Das Problem ist nun, dass beim Aufruf von Close() nichts passiert. D.h. das Fentser bleibt auf. Wenn ich anstatt Close() Dispose() aufrufe geht das Fenster zwar zu, aber Fenster A wird minimiert...

Ich habe zwar eine lösung, aber ich weiß nicht, ob diese wirklich richtig ist:


public static void ShowProgress<TReturn>(String progressText, Object argument, Func<Object, TReturn> doAsync, Action<TReturn> callback, IWin32Window parent = null)
{
	ProgressView progressView = new ProgressView();
	TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
	TaskFactory factory = new TaskFactory(TaskScheduler.Default);
	Action<Task<TReturn>> continueCallback = new Action<Task<TReturn>>((Task<TReturn> task) =>
	{
		progressView.Close();
                progressView.Dispose();	
		Application.DoEvents();
		callback(task.Result);
	});
	factory.StartNew(doAsync, argument).ContinueWith(continueCallback, scheduler);
	progressView.ShowProgress(progressText, null);
}

Könnte mir jemand sagen was ich falsch mache? Bzw. wie man es richtig macht?

Schöne Grüße
Quaneu

29.03.2014 - 09:11 Uhr

Ich glaub ich hab den Fehler gefunden. Ich habe OnApplyTemplate() aufgerufen und damit hat es nie funktioniert. Wenn ich aber ApplyTemplate() aufrufe funktioniert es.

29.03.2014 - 09:05 Uhr

Hallo jogibear9988,

diese Methode kannte ich noch nicht. Hab in Beispielen und Büchern für CustomControls immer die FindName(...) Methode gesehen.
Aber leider funktioniert dies auch nicht, da diese Methode auch null zurück gibt. Es scheint, als ob man das CustomControl noch nicht richtig mit dem Style bzw. Template verbunden ist. Wenn ich nämlich in das Template schaue, finde ich ein Grid mit dem Namen...

Schöne Grüße
Quaneu

29.03.2014 - 00:59 Uhr

Hallo zusammen,

ich habe folgendes Problem. Ich muss zum Testen meines CustomControls das Template per Code setzten. Dies mache ich wie folgt:


Uri uri = new Uri("/XXX;component/Themes/Generic.xaml", UriKind.RelativeOrAbsolute);
ResourceDictionary resourceDictionary = Application.LoadComponent(uri) as ResourceDictionary;
Application application = new Application();
application.Resources = resourceDictionary;

MyCustomControl customControl = new MyCustomControl();

Style style = (Style)Application.Current.Resources[typeof(MyCustomControl)];
customControl.Style= style;
customControl.OnApplyTemplate();

Dies klappt auch sowiet, doch leider funktioniert folgender Code in MyCustomControl nicht richtig:


public override void OnApplyTemplate()
{
	base.OnApplyTemplate();

	if (this.Template != null)
	{
		this._grid = this.Template.FindName("PART_Grid", this) as Grid;
        }
}

Template ist nicht null, aber FindName(...) liefert immer null zurück... Und ich weiß nicht wieso. Im Template gibt es ein Grid, dass PART_Grid heißt.

Kann mir wer sagen, was ich falsch mache?

Schöne Grüße
Quaneu

26.02.2014 - 09:40 Uhr

Hallo emtcho,

vielen Dank für deine schnelle und Ausführliche Hilfe. Ich hatte gehofft ohne Code-Behind auszukommen, doch leider scheint dies nicht zu gehen. Hab mir ein UserControl gebastelt, dass von ComboBox ableitet mit dem entsprechenden Code-Behind. Dies ist dann ein gangbarer Weg 😃.

Schöne Grüße
Quaneu

25.02.2014 - 12:49 Uhr

Hallo Mallett,

diese Idee hatte ich auch schon, aber leider kann man kein Binding in Storyboards verwenden, außer auf sich selbst... Aber trotzdem Danke 😃.

Schöne Grüße
Quanue

24.02.2014 - 20:50 Uhr

Hallo zusammen,

ich habe einen Style für eine ComboBox geschrieben, indem ich über folgendes Problem gestoßen bin.

Ich habe einen Trigger für die Validation:

<Trigger Property="Validation.HasError" Value="True">
	<Setter Property="Border.Background" Value="{StaticResource ErrorBrush}" />
	<Setter Property="ToolTip"
			Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}" />
</Trigger>

Und ein EventTrigger für GotFocus und LostFocus:

<EventTrigger RoutedEvent="ComboBox.GotFocus">
	<BeginStoryboard>
		<Storyboard>
			<ColorAnimation To="{StaticResource FocusedColor}"
					Storyboard.TargetProperty="(ComboBox.Background).(SolidColorBrush.Color)" Duration="0:0:0.3" />
		</Storyboard>
	</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="ComboBox.LostFocus">
	<BeginStoryboard>
		<Storyboard>
			<ColorAnimation To="{StaticResource DarkBackgroundColor}"
					Storyboard.TargetProperty="(ComboBox.Background).(SolidColorBrush.Color)" Duration="0:0:0.3" />
		</Storyboard>
	</BeginStoryboard>
</EventTrigger>

Nun habe ich aber das Problem, wenn Validation.Error == true ist, ist dei Combox rötlich, so weit so gut. Doch wenn ich nun mit der Maus über die Combox gehe und wieder weg, ist sie nicht mehr rötlich, da ja dann der EventTrigger greift. Doch würde ich es gern haben, dass sie immer npch rötlich ist... Leider finde ich keinen schönen Weg...

Hat denn jemand einen guten Hinweis oder gar eine Lösung?

Schöne Grüße
Quaneu

29.08.2013 - 16:35 Uhr

Ich habe es in einem Style und aus diesem kopiert, daher der Setter.

29.08.2013 - 16:15 Uhr

Hallo MillionsterNutzer,

ich glaube mich zu erinneren, dass Du z.B. im Style folgendes schreiben musst:


	<Setter Property="HeadersVisibility" Value="Column" />

Schöne Grüße
Quanue