Встановлення властивостей полів у коді


82
MyControl.Margin.Left = 10;

Помилка:

Неможливо змінити повернене значення 'System.Windows.FrameworkElement.Margin', оскільки воно не є змінною

Відповіді:


138

Проблема полягає в тому, що Marginце властивість, а її тип ( Thickness) - тип значення. Це означає, що коли ви отримуєте доступ до властивості, ви отримуєте копію значення назад.

Незважаючи на те, що ви можете змінити значення Thickness.Leftвластивості для певного значення (grr ... змінні типи значень не повинні існувати), це не змінить поля.

Натомість вам потрібно буде встановити для Marginвластивості нове значення. Наприклад (випадково той самий код, що писав Марк):

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

Як примітка до дизайну бібліотеки, я б дуже віддав перевагу, якби вони Thicknessбули незмінними, але з методами, які повертали нове значення, яке було копією оригіналу, але з однією частиною заміненою. Тоді ви могли написати:

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

Не турбуйтеся про дивну поведінку змінних типів значень, приємний і читабельний, все це один вираз ...


3
похвала за пошук справжнього типу ... Зізнаюсь, я обманював var- гм, вибачте; Я маю на увазі "використання відповідної мовної функції";
p

1
Це допомогло, що повідомлення про помилку містило повну назву типу. Швидкою закладкою для MSDN мені просто знадобився "msdn System.Windows.FrameworkElement.Margin" в адресному рядку, щоб перейти на потрібну сторінку ...
Джон Скіт,

Марк, зволков відкрив нашу таємницю! Виявилося, що отримати надто 200 за день було надто просто, тому я подумав, що поставив перед собою більше виклику та спробую отримати найкращих 2-х користувачів. Отримати "Марка" модератором було просто бонусом ...;)
Джон Скіт,

Але як бути з іншими з нас? Я маю на увазі мене? вони вже знають про сценарій "легіону"?
Марк Гравелл

Чи можу я додати, що ви, хлопці, веселі? Ви працюєте разом поза StackOverflow чи щось інше? Ви всі такі прискіпливі - це змушує мене відчувати себе сторонніми, ха-ха.
Giffyguy

41

MarginВластивість повертає Thicknessструктуру, якій Leftє властивістю. Оператор копіює значення структури із Marginвластивості та встановлює Leftзначення властивості на копії. Ви отримуєте помилку, оскільки встановлене значення не буде зберігатися назад у Marginвластивості.

(Раніші версії C # просто дозволяли це робити без нарікань, викликаючи багато питань у групах новин та форумах, чому таке твердження взагалі не мало ефекту ...)

Щоб встановити властивість, вам потрібно буде отримати Thicknessструктуру з Marginвластивості, встановити значення та зберегти його назад:

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

Якщо ви збираєтеся встановити всі поля, просто створіть Thicknessструктуру і встановіть їх усі відразу:

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

13

Marginповертає структуру, що означає, що ви редагуєте копію . Вам знадобиться щось на зразок:

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

(ура, виправлено деякий час тому ... Я думаю, вам знадобилося оновлення сторінки ;-p)
Марк Гравелл

11

Можна просто цим скористатися

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

4

Можна було б здогадатися, що (а мій WPF зараз трохи іржавий), що Margin бере об’єкт і не може бути безпосередньо змінений.

напр

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

Це не працює: 'System.Windows.FrameworkElement.Margin' є 'властивістю', але використовується як 'тип'
Tor Klingberg

4

Для використання Thicknessвам потрібно створити / змінити .NET frameworkверсію платформи проекту на 4.5. Оскільки цей метод доступний лише у версії 4.5. (Також ви можете просто завантажити PresentationFramework.dll і надати посилання на цю бібліотеку без створення / зміни вашої .NET frameworkверсії на 4.5.)

Але якщо ви хочете зробити це просто, ви можете скористатися таким кодом:

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

також

MyControl.Margin = new Padding(int all);

Це просто і не потребує жодних змін у вашому проекті


3

Залежно від ситуації, ви також можете спробувати використовувати властивість padding тут ...

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

2

Поле = нова товщина (0, 0, 0, 0);


Більше пояснення щодо вашого коду було б непогано. Будь ласка, утримайтеся від просто розміщення коду.
Jackyef

0

Трохи незрозуміло, про що ви питаєте, але, щоб зробити все комфортно, ви можете успадкувати власний Control і додати властивість із кодом, який пропонує Марк:

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

Тоді в коді клієнта ви можете писати просто

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

використання спадщини для вирішення такої проблеми? Досить великі накладні витрати, чи не так?
LuckyLikey

@LuckyLikey, це залежить від випадку використання: якщо ви плануєте змінити MerginLeftдекілька місць у проекті, успадкування дозволяє уникнути проблем із дизайном. Звичайно, якщо це єдине місце у вашому проекті, я б обрав прийняту відповідь.
Ян Туров
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.