Click here to Skip to main content
15,877,637 members
Home / Discussions / C#
   

C#

 
QuestionSSD Computer and Visual Studio 2015... Pin
wtf3218-Jan-17 19:11
wtf3218-Jan-17 19:11 
AnswerRe: SSD Computer and Visual Studio 2015... Pin
Pete O'Hanlon18-Jan-17 19:19
mvePete O'Hanlon18-Jan-17 19:19 
AnswerRe: SSD Computer and Visual Studio 2015... Pin
OriginalGriff18-Jan-17 20:28
mveOriginalGriff18-Jan-17 20:28 
AnswerRe: SSD Computer and Visual Studio 2015... Pin
Nathan Minier19-Jan-17 1:22
professionalNathan Minier19-Jan-17 1:22 
AnswerRe: SSD Computer and Visual Studio 2015... Pin
Eddy Vluggen19-Jan-17 1:51
professionalEddy Vluggen19-Jan-17 1:51 
GeneralRe: SSD Computer and Visual Studio 2015... Pin
wtf3219-Jan-17 2:26
wtf3219-Jan-17 2:26 
AnswerRe: SSD Computer and Visual Studio 2015... Pin
Gerry Schmitz19-Jan-17 5:27
mveGerry Schmitz19-Jan-17 5:27 
QuestionWinforms custom property fails to reload - continued from QA Pin
Midi_Mick18-Jan-17 3:53
professionalMidi_Mick18-Jan-17 3:53 
This is a continuation of Winforms custom property fails to reload - edited[^]. I'm moving it here (a) because the question with different things retried was getting too big and complex, and (b) this format allows for better discussion of the issue.

So, I have changed my code so that each Control object implements ISerializable. The property I am trying to populate is a member of my Component derived object and looks like this:
C#
private DialogControls _controls = new DialogControls();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Editor(typeof(ControlsEditor), typeof(UITypeEditor))]
[Category("Controls")]
[Description("A list of controls that are added to the dialog")]
public DialogControls Controls {
    get { return _controls; }
    set { _controls = value; }
}

bool ShouldSerializeControls() { return Controls.Count > 0; }
void ResetControls() { Controls.Clear(); Controls.ProminentIndex = -1; }

The ControlGroup and DialogControls objects:
C#
[Serializable]
public class ControlGroup : IList<Control>, ICollection, ISerializable {
   public ControlGroup() { }

   List<Control> _controls = new List<Control>();

   #region IList<Control>, ICollection implementation
      // Implemented through _controls
      // ...
   #endregion

   #region ISerializable
   public ControlGroup(SerializationInfo info, StreamingContext context) {
      Control[] controls = (Control[])info.GetValue("controls", typeof(Control[]));
      _controls.AddRange(controls);
   }

   public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
      info.AddValue("controls", _controls.ToArray());
   }
   #endregion
}

[Serializable]
public class DialogControls : ControlGroup, ISerializable {
   public DialogControls() { }
   public int ProminentIndex { get; set; } = -1;
   public Control ProminentControl { get { return ProminentIndex >= 0 ? this[ProminentIndex + 1] : null; } }

   #region ISerializable
   public DialogControls(SerializationInfo info, StreamingContext context) : base(info, context) {
      ProminentIndex = info.GetInt32("prominent");
   }

   public override void GetObjectData(SerializationInfo info, StreamingContext context) {
      base.GetObjectData(info, context);
      info.AddValue("prominent", ProminentIndex);
   }
   #endregion
}

The above is now where the problem occurs. The ControlGroup seems to get serialised, but the individual Control objects do not. Once deserialised, I get an array of nulls.

My Control objects look like this:
C#
[Serializable]
public abstract class Control : ISerializable {
   protected const ControlState DefaultState = ControlState.Enabled | ControlState.Visible;

   public Control() { }
   protected Control(Control other) {
      _state = other._state;
   }
   internal CommonFileDialog _dlg = null;

   internal IFileDialogCustomize fdc { get { return (IFileDialogCustomize)_dlg?._pDialog; } }

   uint _id = 0;
   public uint ID { get { return _id; } internal set { _id = value; } }

   // An enumerated value
   protected ControlState _state = DefaultState;
   public ControlState State {
      get {
         fdc?.GetControlState(ID, out _state);
         return _state;
      }
      set {
         _state = value;
         fdc?.SetControlState(ID, _state);
      }
   }

   internal abstract void AddToDialog(CommonFileDialog owner);
   internal abstract bool CanMakeProminent { get; }
   internal abstract string Value { get; }
   internal abstract string Description { get; }
   internal abstract string Type { get; }
   public abstract Control Clone();

   #region ISerializable

   // _state is the only field I need serialised here. ID and _dlg are not set until runtime.
   public Control(SerializationInfo info, StreamingContext context) {
      _state = (ControlState)info.GetValue("state", typeof(ControlState));
   }

   public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
      info.AddValue("state", State);
   }
   #endregion
}

I then inherit each of the controls (there are a dozen of them, but they all follow the same pattern) like this:
C#
[Serializable]
public sealed class CheckBox : Control, ISerializable {

   string _label;
   public string Label {
      get {
         return _label;
      }
      set {
         _label = value;
         fdc?.SetControlLabel(ID, _label);
      }
   }
   internal bool _checked;
   public bool Checked {
      get {
         return _checked;
      }
      set {
         _checked = value;
         fdc?.SetCheckButtonState(ID, _checked);
      }
   }

   public CheckBox() { }
   CheckBox(CheckBox other) : base(other) { _label = other._label; _checked = other._checked; }
   public CheckBox(string label, bool check) {
      Label = label;
      Checked = check;
   }

   #region ISerializable
   public CheckBox(SerializationInfo info, StreamingContext context) : base(info, context) {
      _label = info.GetString("label");
      _checked = info.GetBoolean("checked");
   }

   public override void GetObjectData(SerializationInfo info, StreamingContext context) {
      base.GetObjectData(info, context);
      info.AddValue("label", _label);
      info.AddValue("checked", _checked);
   }
   #endregion

   #region Control overrides
   internal override void AddToDialog(CommonFileDialog dlg) {
      // This is where the _dlg and ID properties are set at runtime, and the controls are actually added to the fdc
   }
   internal override bool CanMakeProminent { get { return true; } }
   internal override string Type { get; } = "CheckBox";
   internal override string Description { get { return Label; } }
   internal override string Value { get { return Checked.ToString(); } }
   public override Control Clone() { return new CheckBox(this); }
   public override string ToString() {
      return string.Format("{0}({1}, {2})", Type, Description, Value);
   }
   #endregion
}

Cheers,

Mick
------------------------------------------------
It doesn't matter how often or hard you fall on your arse, eventually you'll roll over and land on your feet.

AnswerRe: Winforms custom property fails to reload - continued from QA Pin
Gerry Schmitz18-Jan-17 4:47
mveGerry Schmitz18-Jan-17 4:47 
GeneralRe: Winforms custom property fails to reload - continued from QA Pin
Midi_Mick18-Jan-17 4:54
professionalMidi_Mick18-Jan-17 4:54 
GeneralRe: Winforms custom property fails to reload - continued from QA Pin
Gerry Schmitz18-Jan-17 5:19
mveGerry Schmitz18-Jan-17 5:19 
GeneralRe: Winforms custom property fails to reload - continued from QA Pin
Midi_Mick18-Jan-17 5:34
professionalMidi_Mick18-Jan-17 5:34 
QuestionRe: Winforms custom property fails to reload - continued from QA. A new clue. Pin
Midi_Mick18-Jan-17 4:48
professionalMidi_Mick18-Jan-17 4:48 
QuestionWhen is it safe to use Monitor (lock) with Task? Pin
Bernhard Hiller18-Jan-17 2:34
Bernhard Hiller18-Jan-17 2:34 
AnswerRe: When is it safe to use Monitor (lock) with Task? Pin
Pete O'Hanlon18-Jan-17 3:25
mvePete O'Hanlon18-Jan-17 3:25 
GeneralRe: When is it safe to use Monitor (lock) with Task? Pin
Bernhard Hiller18-Jan-17 21:05
Bernhard Hiller18-Jan-17 21:05 
AnswerRe: When is it safe to use Monitor (lock) with Task? Pin
Richard Deeming18-Jan-17 8:11
mveRichard Deeming18-Jan-17 8:11 
GeneralRe: When is it safe to use Monitor (lock) with Task? Pin
Bernhard Hiller18-Jan-17 21:11
Bernhard Hiller18-Jan-17 21:11 
GeneralRe: When is it safe to use Monitor (lock) with Task? Pin
Pete O'Hanlon18-Jan-17 21:15
mvePete O'Hanlon18-Jan-17 21:15 
QuestionGroup of Checkboxes Pin
eejaynic17-Jan-17 11:41
eejaynic17-Jan-17 11:41 
AnswerRe: Group of Checkboxes Pin
Gerry Schmitz17-Jan-17 13:02
mveGerry Schmitz17-Jan-17 13:02 
GeneralRe: Group of Checkboxes Pin
eejaynic17-Jan-17 14:11
eejaynic17-Jan-17 14:11 
GeneralRe: Group of Checkboxes Pin
Gerry Schmitz17-Jan-17 14:53
mveGerry Schmitz17-Jan-17 14:53 
AnswerRe: Group of Checkboxes Pin
Richard Deeming18-Jan-17 2:04
mveRichard Deeming18-Jan-17 2:04 
GeneralRe: Group of Checkboxes Pin
eejaynic18-Jan-17 9:03
eejaynic18-Jan-17 9:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.