미안하지만이 은이어야 복제본인데 StackOverflow에서이 질문에 대한 답을 찾을 수 없었습니다. 나는 다중 상속이 불가능하다는 것을 알고있다.동일한 인터페이스를 구현하는 많은 사용자 지정 사용자 컨트롤. 각각에 동일한 코드가 중복되는 것을 피할 수있는 방법이 있습니까?
내 응용 프로그램에는 50 개 클래스의 사용자 지정 사용자 정의 컨트롤이 있으며, 모두 내 IParamConfig 인터페이스를 구현합니다.
IParamConfig는 5 개의 속성과 8 개의 메서드를 정의합니다. 이러한 사용자 정의 사용자 컨트롤의
가, 일부는 텍스트 상자에서 상속 등의 버튼에서 몇 가지 체크 상자의 일부, 콤보 상자에서 일부나는 방법 및 IParamConfig의 속성을 구현하는 ParamConfig 클래스를 만들 수 있습니다; 하지만 나는 각 사용자 정의 컨트롤 클래스가 ParamConfig와 TextBox 또는 다른 사용자 컨트롤 클래스로부터 상속받을 수 없다는 것을 알고 있습니다.
따라서 IParamConfig의 메서드 및 속성 구현을 여러 번 반복해야합니다.
예를 들어 TextBox에서 상속받은 추상 클래스 AbtrParamConfigTextBox를 만들고 IParamConfig의 메서드 및 속성을 구현합니다. 그런 다음이 추상 클래스에서 상속 된 많은 TextBox와 같은 사용자 지정 사용자 정의 컨트롤을 만들었습니다.
마찬가지로, ComboBox에서 상속 받고 IParamConfig의 메서드 및 속성도 구현하는 추상 클래스 AbtrParamConfigComboBox를 만들었습니다.
총에, 나는 (그림에서 빨간색 상자) 공통의 코드 12 번을 복제했다.
공통 코드를 한 번만 표시 할 수 있다면 좋겠어요.
예를 들어 모든 사용자 지정 사용자 지정 컨트롤이 동일한 클래스 (ParamConfig)에서 상속받을 수 있다면 좋겠습니다.
나는 일을 시도하는 UserControl에서 상속 ParamConfig 클래스를 생성 한 다음 하나의 텍스트 상자를 포함 ParamConfig에서 상속 ParamConfigTextBox을 만들어.
그러나 ParamConfigTextBox의 속성을 복사하는 코드를 내가 더 이상 ParamConfigTextBox에서 TextBox의 속성에 직접 액세스 할 수 없습니다, 그래서 ParamConfigTextBox에서 그들을 복제해야하고, 추가하기 때문에 즉, 어색 해결 방법 결과 텍스트 상자에. 추한.
질문 : 공통 코드 12 번을 복제하는 데에 갇혀
건가요?
UserControl에서 상속하는 공통 클래스 방식을 추구해야합니까?
더 깨끗한 해결책이 있습니까?
EDIT : 요청한대로 사용자 인터페이스의 스크린 샷. 이 제품에는 ~ 100 개의 탭이 있으며, 각 탭에는 제품 구성을위한 사용자 컨트롤이 가득합니다.
편집 :
인터페이스 :
// Functions
string BmsParamName { get; } // Name of the parameter in the BMS's memory associated with this control
void InitControlOnLoad(); // Initialize the control after load
void ClearCtrl(); // Clear this control
uint BitsUsedMask(); // Return the mask for the bits used in memory
void ShowValue16(ushort paramWord, bool isBadData); // Update the value or state displayed by this control
void ShowValue32(uint paramValue32, bool isBadData); // Update the value or state displayed by this control
uint NoOfBmsMemWords(); // Return the number of BMS memory words that this set uses
void ShowParamArray(uint[] paramValues, uint bmsMemOfst, bool isBadData); // Update the value or state displayed by this control
ushort GetEntry16(ushort configWord); // Receive the full word of configuration data and return it after replacing those bits that this configuration control is responsible for
uint GetEntry32(); // Return the value in this control as a 16 bit unsigned integer
ushort[] GetEntryArray(); // Get the set of configuration words for this configuration control
속성 :
#region Properties (Protected properties, available to inherited classes)
// Name of BMS variable
protected string bmsParamName = "";
[DefaultValueAttribute(0), Category("_Vinci"),
Description("Name of the variable in the BMS's memory associated with this control")]
public string BmsParamName
{
get { return bmsParamName; }
set { bmsParamName = value; }
}
// Conversion factor
protected float conversionFactor = 1F;
[DefaultValueAttribute(1),
Description("To convert the BMS value to the value shown in this setting, divide by this factor"),
Category("_Vinci")]
public float ConversionFactor
{
get { return conversionFactor; }
set { conversionFactor = value; }
}
// Width of the data
protected VinciForm.DataWidth dataWidth = VinciForm.DataWidth.Data16;
[DefaultValueAttribute(VinciForm.DataWidth.Data16),
Description("Whether the data in the BMS fill an entire 32 bit word, a 16 bit Word, just the top 8 bits (MSB), the lower 8 bits (LSB), or specific bits"),
Category("_Vinci")]
public VinciForm.DataWidth DataWidth
{
get { return dataWidth; }
set
{
dataWidth = value;
firstBitNo = 0u;
switch (dataWidth)
{
case VinciForm.DataWidth.Data32:
noOfBits = 32u;
break;
case VinciForm.DataWidth.Data16:
noOfBits = 16u;
break;
case VinciForm.DataWidth.Data8LSB:
noOfBits = 8u;
break;
case VinciForm.DataWidth.Data8MSB:
firstBitNo = 8u;
noOfBits = 8u;
break;
case VinciForm.DataWidth.DataBits:
noOfBits = 16u;
break;
}
}
}
// Number of the least significant bit used
protected uint firstBitNo = 0u;
[DefaultValueAttribute(0), Category("_Vinci"),
Description("Number of the least significant bit used")]
public uint FirstBitNo
{
get { return firstBitNo; }
set { firstBitNo = value; }
}
// Number of bits used
protected uint noOfBits = 16u;
[DefaultValueAttribute(3), Category("_Vinci"),
Description("Number of bits used")]
public uint NoOfBits
{
get { return noOfBits; }
set { noOfBits = value; }
}
// Display format: unsigned, signed or hex
protected VinciForm.DisplayFormat displayFrmtCode = VinciForm.DisplayFormat.UnsignedFormat;
[DefaultValueAttribute(VinciForm.DataWidth.Data16),
Description("Display format: unsigned, signed or hex"),
Category("_Vinci")]
public VinciForm.DisplayFormat DisplayFormat
{
get { return displayFrmtCode; }
set { displayFrmtCode = value; }
}
// Format string
protected string displayFrmtStr = "";
[DefaultValueAttribute(""),
Description("Display format string (e.g.: F4 for 4 decimal places); leave blank for automatic"),
Category("_Vinci")]
public virtual string DisplayFrmtStr
{
get { return displayFrmtStr; }
set { displayFrmtStr = value; }
}
#endregion
인터페이스를 확인하는 것이 좋습니다. 그렇지 않으면 응답이 모호합니다. – Sefe
왜 TextBox에 직접 액세스 할 수 없습니까? 비공개로 만들었 니? 보호 된 액세스 수정자가있는 특성으로이를 추가하는 경우, 하위 클래스는이를 직접 사용할 수 있어야합니다. – chadnt
@Sefe 사용자 인터페이스의 스크린 샷을 추가했습니다 –