Establecer propiedades de margen en el código

81
MyControl.Margin.Left = 10;

Error:

No se puede modificar el valor de retorno de 'System.Windows.FrameworkElement.Margin' porque no es una variable

Giffyguy
fuente

Respuestas:

137

El problema es que Margines una propiedad y su tipo ( Thickness) es un tipo de valor. Eso significa que cuando accede a la propiedad, obtiene una copia del valor.

Aunque puede cambiar el valor de la Thickness.Leftpropiedad para un valor particular (grr ... los tipos de valores mutables no deberían existir), no cambiaría el margen.

En su lugar, deberá establecer la Marginpropiedad en un nuevo valor. Por ejemplo (casualmente el mismo código que escribió Marc):

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

Como nota para el diseño de la biblioteca, lo hubiera preferido mucho si Thicknessfuera inmutable, pero con métodos que devolvían un nuevo valor que era una copia del original, pero con una parte reemplazada. Entonces podrías escribir:

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

No se preocupe por el comportamiento extraño de los tipos de valores mutables, agradable y legible, todo una expresión ...

Jon Skeet
fuente
3
felicitaciones por buscar el tipo real ... Confieso haber hecho trampa con var- ejem, lo siento; Me refiero a "usar una función de lenguaje adecuada" ;-p
Marc Gravell
1
Ayudó que el mensaje de error contenía el nombre de tipo completo. Con un marcador rápido para MSDN, solo necesitaba "msdn System.Windows.FrameworkElement.Margin" en la barra de direcciones para llegar a la página correcta ...
Jon Skeet
¡Marc, zvolkov ha descubierto nuestro secreto! Resultó que era demasiado fácil conseguir 200 en un día, así que pensé en plantearme un desafío mayor y tratar de conseguir los 2 mejores usuarios. Tener a "Marc" como moderador fue solo una ventaja ...;)
Jon Skeet
Pero, ¿qué pasa con los demás? ¿Me refiero a mi? ¿Conocen ya el guión de "legion"?
Marc Gravell
¿Puedo agregar que ustedes son divertidísimos? ¿Trabajan juntos fuera de StackOverflow o algo así? Todos ustedes son tan amistosos, me hace sentir como un extraño, jaja.
Giffyguy
40

La Marginpropiedad devuelve una Thicknessestructura, de la cual Leftes una propiedad. Lo que hace la declaración es copiar el valor de la estructura de la Marginpropiedad y establecer el valor de la Leftpropiedad en la copia. Obtiene un error porque el valor que estableció no se almacenará nuevamente en la Marginpropiedad.

(Las versiones anteriores de C # simplemente le permitían hacerlo sin quejarse, lo que generaba muchas preguntas en los grupos de noticias y foros sobre por qué una declaración como esa no tenía ningún efecto ...)

Para establecer la propiedad, necesitaría obtener la Thicknessestructura de la Marginpropiedad, establecer el valor y almacenarlo nuevamente:

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

Si va a establecer todos los márgenes, simplemente cree una Thicknessestructura y configúrelos todos a la vez:

MyControl.Margin = new Thickness(10, 10, 10, 10);
Guffa
fuente
13

Margindevuelve una estructura, lo que significa que está editando una copia . Necesitará algo como:

var margin = MyControl.Margin;
margin.Left = 10;
MyControl.Margin = margin;
Marc Gravell
fuente
(salud, solucionado hace algún tiempo ... espero que necesitaras una actualización de página ;-p)
Marc Gravell
11

Uno podría simplemente usar esto

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

Uno diría que (y mi WPF está un poco oxidado en este momento) que Margin toma un objeto y no se puede cambiar directamente.

p.ej

MyControl.Margin = new Margin(10,0,0,0);
Ceniza
fuente
Esto no funciona: 'System.Windows.FrameworkElement.Margin' es una 'propiedad' pero se usa como un 'tipo'
Tor Klingberg
4

Para usarlo Thickness, debe crear / cambiar la .NET frameworkversión de la plataforma de su proyecto a 4.5. porque este método está disponible solo en la versión 4.5. (También puede descargar PresentationFramework.dll y dar referencia a este dll, sin crear / cambiar su .NET frameworkversión a 4.5).

Pero si quieres hacer esto simple, puedes usar este código:

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

además

MyControl.Margin = new Padding(int all);

Esto es simple y no necesita cambios en su proyecto.

Daler Tursunov
fuente
3

Depende de la situación, también puede intentar usar la propiedad de relleno aquí ...

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

Margen = nuevo Espesor (0, 0, 0, 0);

KalleP
fuente
Sería bueno recibir más explicaciones sobre su código. Abstente de publicar el código.
Jackyef
0

No está claro qué estás preguntando, pero para hacer las cosas cómodas, puedes heredar tu propio Control y agregar una propiedad con el código que sugiere Marc:

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

Luego, en el código del cliente, puede escribir solo

MyImage img = new MyImage();
img.MarginLeft = 10;
MessageBox.Show(img.Margin.Left.ToString()); // or img.MarginLeft
Jan Turoň
fuente
usando la herencia para resolver tal problema? Una sobrecarga bastante grande, ¿no?
LuckyLikey
@LuckyLikey depende del caso de uso: si planea alterar el MerginLeften varios lugares del proyecto, la herencia evita problemas de diseño. Por supuesto, si este es un lugar único en su proyecto, elegiría la respuesta aceptada.
Jan Turoň