Festlegen der Randeigenschaften im Code


81
MyControl.Margin.Left = 10;

Error:

Der Rückgabewert von 'System.Windows.FrameworkElement.Margin' kann nicht geändert werden, da es sich nicht um eine Variable handelt

Antworten:


137

Das Problem ist, dass Margines sich um eine Eigenschaft handelt und dass type ( Thickness) ein Werttyp ist. Das heißt, wenn Sie auf die Eigenschaft zugreifen, erhalten Sie eine Kopie des Werts zurück.

Obwohl Sie den Wert der Eigenschaft für einen bestimmten Wert ändern könnenThickness.Left (grr ... veränderbare Werttypen sollten nicht vorhanden sein), wird der Rand nicht geändert.

Stattdessen müssen Sie die MarginEigenschaft auf einen neuen Wert setzen. Zum Beispiel (zufällig der gleiche Code wie Marc):

Thickness margin = MyControl.Margin;
margin.Left = 10;
MyControl.Margin = margin;

Als Hinweis für das Bibliotheksdesign hätte ich es sehr bevorzugt, wenn Thicknesses unveränderlich gewesen wäre, aber mit Methoden, die einen neuen Wert zurückgaben, der eine Kopie des Originals war, aber einen Teil ersetzte. Dann könnten Sie schreiben:

MyControl.Margin = MyControl.Margin.WithLeft(10);

Keine Sorge um seltsames Verhalten von veränderlichen Werttypen, nett und lesbar, alles ein Ausdruck ...


3
Ein vargroßes Lob für das Nachschlagen des tatsächlichen Typs ... Ich gestehe, mit - ähm, sorry; Ich meine "Verwenden einer geeigneten Sprachfunktion" ;-p
Marc Gravell

1
Es hat geholfen, dass die Fehlermeldung den vollständig qualifizierten Typnamen enthielt. Mit einem schnellen Lesezeichen für MSDN brauchte ich nur "msdn System.Windows.FrameworkElement.Margin" in der Adressleiste, um zur richtigen Seite zu gelangen ...
Jon Skeet

Marc, Zvolkov hat unser Geheimnis entdeckt! Es stellte sich heraus, dass es viel zu einfach war, 200 an einem Tag zu bekommen, also dachte ich, ich würde mich einer größeren Herausforderung stellen und versuchen, die Top-2-Benutzer zu erreichen. "Marc" als Moderator zu bekommen war nur ein Bonus ...;)
Jon Skeet

Aber was ist mit den anderen von uns? Ich meine mich? Wissen sie schon über das "Legion" -Skript Bescheid?
Marc Gravell

Kann ich hinzufügen, dass ihr komisch seid? Arbeiten Sie außerhalb von StackOverflow zusammen oder so? Ihr seid alle so befreundet - ich fühle mich wie ein Außenseiter, haha.
Giffyguy

40

Die MarginEigenschaft gibt eine ThicknessStruktur zurück, von der Lefteine Eigenschaft ist. Die Anweisung kopiert den Strukturwert aus der MarginEigenschaft und legt den LeftEigenschaftswert für die Kopie fest. Sie erhalten eine Fehlermeldung, da der von Ihnen festgelegte Wert nicht wieder in der MarginEigenschaft gespeichert wird .

(In früheren Versionen von C # konnten Sie dies einfach tun, ohne sich zu beschweren, was in Newsgroups und Foren viele Fragen dazu verursachte, warum eine solche Aussage überhaupt keine Wirkung hatte ...)

Um die Eigenschaft festzulegen, müssen Sie die ThicknessStruktur aus der MarginEigenschaft abrufen, den Wert festlegen und zurückspeichern:

Thickness m = MyControl.Margin;
m.Left = 10;
MyControl.Margin = m;

Wenn Sie alle Ränder festlegen möchten, erstellen Sie einfach eine ThicknessStruktur und legen Sie alle gleichzeitig fest:

MyControl.Margin = new Thickness(10, 10, 10, 10);

13

Margingibt eine Struktur zurück, was bedeutet, dass Sie eine Kopie bearbeiten . Sie benötigen so etwas wie:

var margin = MyControl.Margin;
margin.Left = 10;
MyControl.Margin = margin;

(Prost, vor einiger Zeit behoben ... Ich nehme an, Sie brauchten eine Seitenaktualisierung ;-p)
Marc Gravell

11

Man könnte das einfach benutzen

MyControl.Margin = new System.Windows.Thickness(10, 0, 5, 0);

4

Man würde vermuten (und mein WPF ist momentan ein wenig verrostet), dass Margin ein Objekt nimmt und nicht direkt geändert werden kann.

z.B

MyControl.Margin = new Margin(10,0,0,0);

Dies funktioniert nicht: 'System.Windows.FrameworkElement.Margin' ist eine 'Eigenschaft', wird aber wie ein 'Typ' verwendet
Tor Klingberg

4

Zur Verwendung müssen ThicknessSie Ihre Projektplattformversion .NET frameworkauf 4.5 erstellen / ändern . da diese Methode nur in Version 4.5 verfügbar ist. (Sie können auch einfach PresentationFramework.dll herunterladen und auf diese DLL verweisen, ohne Ihre .NET frameworkVersion auf 4.5 zu erstellen / zu ändern .)

Wenn Sie dies jedoch einfach tun möchten, können Sie diesen Code verwenden:

MyControl.Margin = new Padding(int left, int top, int right, int bottom);

ebenfalls

MyControl.Margin = new Padding(int all);

Dies ist einfach und erfordert keine Änderungen an Ihrem Projekt


3

Abhängig von der Situation können Sie hier auch die Padding-Eigenschaft verwenden ...

MyControl.Margin=new Padding(0,0,0,0);

2

Rand = neue Dicke (0, 0, 0, 0);


Weitere Erklärungen zu Ihrem Code wären nett. Bitte verzichten Sie nur auf die Postleitzahl.
Jackyef

0

Es ist ein bisschen unklar, was Sie fragen, aber um es sich bequem zu machen, können Sie Ihr eigenes Steuerelement erben und eine Eigenschaft mit dem von Marc vorgeschlagenen Code hinzufügen:

class MyImage : Image {
    private Thickness thickness;
    public double MarginLeft {
        get { return Margin.Left; }
        set { thickness = Margin; thickness.Left = value; Margin = thickness; }
    }
}

Dann können Sie im Client-Code einfach schreiben

MyImage img = new MyImage();
img.MarginLeft = 10;
MessageBox.Show(img.Margin.Left.ToString()); // or img.MarginLeft

Vererbung verwenden, um ein solches Problem zu lösen? Ziemlich viel Aufwand, nicht wahr?
LuckyLikey

@LuckyLikey hängt vom Anwendungsfall ab: Wenn Sie MerginLeftvorhaben, die an mehreren Stellen im Projekt zu ändern , werden durch die Vererbung Entwurfsprobleme vermieden. Wenn dies ein einzelner Ort in Ihrem Projekt ist, würde ich natürlich die akzeptierte Antwort wählen.
Jan Turoň
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.