Редактор Visual Studio WinForms не сохраняет изменения в пользовательской коллекции [закрыто]C#

Место общения программистов C#
Ответить
Anonymous
 Редактор Visual Studio WinForms не сохраняет изменения в пользовательской коллекции [закрыто]

Сообщение Anonymous »

Я пытаюсь отредактировать свойство коллекции для пользовательского элемента управления UserControl с помощью редактора коллекций, но внесенные мной изменения не сохраняются. Коллекция представляет собой собственный класс, являющийся подклассом List. Редактор коллекций позволяет мне добавлять нужные значения, не выдает никаких ошибок и даже обновляет элемент управления в дизайнере, чтобы он выглядел так, как должен выглядеть элемент управления с новыми значениями в списке. Однако он не создает ресурс для измененного списка и не генерирует код в файле Designer для десериализации списка и установки свойства для сохраненного списка. Мой класс пользовательского списка имеет атрибут Serializable, и я также попытался добавить к свойству атрибут Editor(typeof(CollectionEditor), typeof(UITypeEditor)), но он все равно не сохраняется. Я попробовал использовать обычное свойство List и смог его сохранить.
Вот именно то, о чем я говорю. Вот редактор коллекции, и я могу добавить следующие значения:
[img]https: //i.sstatic.net/Y2fUyNx7.png[/img]

Я нажимаю «ОК». В дизайнере, если сделать это правильно, связанный элемент управления UserControl будет выглядеть следующим образом:
Изображение

Однако, когда я собираю и запускаю программу, UserControl выглядит так, как если бы список не предоставлен:
Изображение

Если после этого я посмотрю на дизайнер, он через несколько секунд обновится до указанного выше значения по умолчанию.
проблема в том, что он не сохраняет ресурс для измененного list:
Изображение

Он также не генерирует код, аналогичный notifierListLabel1.Ints = (DataClasses.NotifierList)resources.GetObject("notifierListLabel1.Ints") в файле дизайнера.
Что мне не хватает? Есть ли какие-то атрибуты, которых мне не хватает? Мне не удалось найти ничего об этом в Интернете.
Изменить: Я загрузил соответствующий код здесь:
https://drive.google.com/file/d/1e4t2Z4 ... sp=sharing
Измените еще раз: Вот код, который Я думаю, есть проблема:

Код: Выделить всё

using SaveableCounters.DataClasses;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Drawing;
using System.Drawing.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SaveableCounters.UserControls
{
[DefaultEvent(nameof(OnTextChanged))]
public partial class Counter2 : UserControl
{
[Browsable(true)]
public int Count
{
get => int.Parse(counterField.Text);
set => counterField.Text = value.ToString();
}
public string CountAsText => counterField.Text;

private NotifierList stepSizes;
[Browsable(true)]
// [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] this makes it work but it shouldn't need to have this
public NotifierList StepSizes
{
get => stepSizes;
set
{
stepSizes = value;
if (stepSizes is null)
return;

stepSizes.CollectionChanged += CreateButtonsForStepSizes;
CreateButtonsForStepSizesActual();
}
}

private List currentCounterButtons = new List();

private const int buttonDefaultWidthAndHeight = 39;
private int buttonBaseWidth;
private int counterFieldBaseWidth;

public Counter2(int startingCount, IEnumerable stepSizes)
{
InitializeComponent();

Count = startingCount;
buttonBaseWidth = buttonDefaultWidthAndHeight - TextRenderer.MeasureText("+", counterField.Font).Width;
counterFieldBaseWidth = buttonDefaultWidthAndHeight - TextRenderer.MeasureText(startingCount.ToString(), counterField.Font).Width;
counterField.Width = buttonDefaultWidthAndHeight;

counterField.TextChanged += ResizeCounterField;
StepSizes = new NotifierList(stepSizes);
}

public Counter2(int startingCount) : this(startingCount, new int[] { 1 })
{
}

public Counter2() : this(0)
{
}

[Browsable(true)]
public new event EventHandler? OnTextChanged
{
add => counterField.TextChanged += value;
remove => counterField.TextChanged -= value;
}

[Browsable(true)]
public new event CancelEventHandler? Validating
{
add => counterField.Validating += value;
remove => counterField.Validating -= value;
}

[Browsable(true)]
public new event EventHandler? Validated
{
add => counterField.Validated += value;
remove =>  counterField.Validated -= value;
}

protected virtual void CreateButtonsForStepSizes(object? sender, NotifyCollectionChangedEventArgs e)
{
CreateButtonsForStepSizesActual();
}

private void CreateButtonsForStepSizesActual()
{
contents.SuspendLayout();
SuspendLayout();

foreach (Button button in currentCounterButtons)
{
contents.Controls.Remove(button);
}
currentCounterButtons.Clear();

foreach (int stepSize in StepSizes)
{
Button countDownButton = new Button();
Button countUpButton = new Button();

if (stepSize == 1)
{
countDownButton.Text = "-";
countUpButton.Text = "+";
}
else
{
countDownButton.Text = $"-{stepSize}";
countUpButton.Text = $"+{stepSize}";
}

int textWidth = Math.Max(
TextRenderer.MeasureText(countDownButton.Text, countDownButton.Font).Width,
TextRenderer.MeasureText(countUpButton.Text, countUpButton.Font).Width
);

Console.WriteLine($"{buttonBaseWidth} {textWidth}");
Size buttonSize = new Size(buttonBaseWidth + textWidth, buttonDefaultWidthAndHeight);
countDownButton.Size = buttonSize;
countUpButton.Size = buttonSize;

countDownButton.Margin = Padding.Empty;
countUpButton.Margin = Padding.Empty;

countDownButton.Click += (_, _) => Count -= stepSize;
countUpButton.Click += (_, _) => Count += stepSize;

contents.Controls.Add(countDownButton);
contents.Controls.SetChildIndex(countDownButton, 0);
contents.Controls.Add(countUpButton);

currentCounterButtons.Add(countDownButton);
currentCounterButtons.Add(countUpButton);
}

ResumeLayout();
contents.ResumeLayout();
}

private void ResizeCounterField(object? sender, EventArgs e)
{
int newWidth = counterFieldBaseWidth + TextRenderer.MeasureText(counterField.Text, counterField.Font).Width;
counterField.Width = newWidth;
}

private void counterField_Validating(object sender, CancelEventArgs e)
{
if (!int.TryParse(CountAsText, out _))
e.Cancel = true;
}
}
}
Я пытался сделать минимальный пример, но на самом деле для него сохранилась коллекция. Я думал, что это означает, что мне просто нужно удалить и переделать форму с проблемой, но это не решило проблему, поэтому я предоставляю реальный код. В коде есть настраиваемый список (NotifierList), UserControl (Counter2) и форма (SaveableCountersForm). Я не могу использовать ObservableCollection, потому что при попытке сериализации он выдает ошибку из-за невозможности загрузить тип "System.Collections.ObjectModel.SimpleMonitor"
, о котором я не смог найти никакой информации. об Интернете.

Подробнее здесь: https://stackoverflow.com/questions/792 ... collection
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»