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

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


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);

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;

(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);

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);

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.


3

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

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

2

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


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

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ň
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.