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

Giffyguy
quelle

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 ...

Jon Skeet
quelle
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);
Guffa
quelle
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;
Marc Gravell
quelle
(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);
LuckyLikey
quelle
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);
Asche
quelle
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

Daler Tursunov
quelle
3

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

MyControl.Margin=new Padding(0,0,0,0);
Rishi
quelle
2

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

KalleP
quelle
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
Jan Turoň
quelle
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ň