.net code>将返回以2为底的xmod 5的对数,即2n=xmod 5中的n(同样,解释得很好)
由于.net code>将返回以2为底的xmod 5的对数,即2n=xmod 5中的n(同样,解释得很好),.net,string,vb.net,button,alignment,.net,String,Vb.net,Button,Alignment,由于xmod 5只能是0-4范围内的整数,Log(xmod 5,2)只能返回0-2范围内的指数(n)(22=4) 现在,由于ContentAlignment枚举仅由二进制数组成,2n中的n将始终是一个整数,因此0、1或2-这正是我们所需要的,因为StringAlignment枚举只有这三个值问题解决了 在线测试: 垂直解(解释) 在我看来,垂直解决方案有点“黑客”,但它是有效的 由于存在相同对齐方式的整个范围(例如16-64),因此垂直解决方案更难一些,我认为最简单的方法是,如果我能以某种方式
xmod 5
只能是0-4范围内的整数,Log(xmod 5,2)
只能返回0-2范围内的指数(n
)(22=4
)
现在,由于ContentAlignment
枚举仅由二进制数组成,2n
中的n
将始终是一个整数,因此0、1或2-这正是我们所需要的,因为StringAlignment
枚举只有这三个值问题解决了强>
在线测试:
垂直解(解释) 在我看来,垂直解决方案有点“黑客”,但它是有效的 由于存在相同对齐方式的整个范围(例如16-64),因此垂直解决方案更难一些,我认为最简单的方法是,如果我能以某种方式获得大于或等于所需对齐方式的十进制数,然后将其四舍五入 这就是我提出的公式:
Floor(Log(x, 16))
将返回以Log(x,16)
为底的16
的对数,因此x
在n
中16n=x
对于二进制数n
将是一个整数和0-2个四分之一(例如n
,1
,1.25
等)1.5
将返回Floor(Log(x,16))
向下取整的结果(例如Log(x,16)
)1.5->1
+------------+--------------+-------------------+
|二元|对数(x,16)|层(对数(x,16))|
+------------+--------------+-------------------+
| 256 | 2 | 2 |
| 512 | 2.25 | 2 |
| 1024 | 2.50 | 2 |
+------------+--------------+-------------------+
在线测试:
最终解决方案 最后,利用这些信息,我们现在可以创建一个相对较小的函数,为我们进行所需的转换:
Public Function ContentToStringAlignment(ByVal Alignment As ContentAlignment, ByVal Vertical As Boolean) As StringAlignment
If Vertical = True Then Return CType(Math.Floor(Math.Log(CType(Alignment, Integer), 16)), StringAlignment)
Return CType(Math.Log(CType(Alignment, Integer) Mod 5, 2), StringAlignment)
End Function
用法:
oStringFormat.LineAlignment = ContentToStringAlignment(goTextAlign, True) 'True for vertical alignment.
oStringFormat.Alignment = ContentToStringAlignment(goTextAlign, False)
在线测试:不使用对数的更好答案
这是假设ControlAlignment中只设置了一个位,但是使用Math.Log的解决方案也存在多个位值的问题
这都是C#语法,很抱歉。。。我也希望这些在这篇文章的抄写中没有丢失任何东西
假设ca
是初始ContentAlignment
值,表示为十六进制数,则其形式为0xBMT
,其中B、M和T代表底部、中间和顶部,且每一个都具有二进制形式0RCL
,其中R、C、L表示右(远)、中、左(近)
提取水平对齐
通过0x111
的乘法将B、M和T值在B位置相加(因此ORs是一个位)。右移9将B位置转换为形式为RC
的二进制数,其值为2、1或0。final&操作删除乘法创建的B位置上方的垃圾
提取垂直对齐
乘以7将RCL位添加到每个BMT十六进制数字内的R位置(因此ORs是一个位)。与0x444
进行ANDing只保留每个BMT十六进制数字中的R位(现在是R、C和L的OR)。通过0x49相乘
将M组和T组的R位的副本置于B组的副本之下。shift和&的操作与提取水平对齐中的操作相同
用ta
与水平情况类似,第一项生成所有L、C和R,这些L、C和R的位置适合于所需的垂直对齐。第二项将每个LCR位的B、M和T合并到B组的LCR中。与0x700
进行ANDing只保留B组,与0x111
相乘并右移8可产生在所有三个BMT组中重复的原始L、C或R位。不使用对数的更好答案
这是假设ControlAlignment中只设置了一个位,但是使用Math.Log的解决方案也存在多个位值的问题
这都是C#语法,很抱歉。。。我也希望这些在这篇文章的抄写中没有丢失任何东西
假设ca
是初始ContentAlignment
值,表示为十六进制数,则其形式为0xBMT
,其中B、M和T代表底部、中间和顶部,且每一个都具有二进制形式0RCL
,其中R、C、L表示右(远)、中、左(近)
提取水平对齐
通过0x111
的乘法将B、M和T值在B位置相加(因此ORs是一个位)。右移9将B位置转换为形式为RC
的二进制数,其值为2、1或0。final&操作删除乘法创建的B位置上方的垃圾
提取垂直对齐
乘以7将RCL位添加到每个BMT十六进制数字内的R位置(因此ORs是一个位)。与0x444
进行ANDing只保留每个BMT十六进制数字中的R位(现在是R、C和L的OR)。通过0x49相乘
将M组和T组的R位的副本置于B组的副本之下。shift和&的操作与提取水平对齐中的操作相同
用ta
与水平情况类似,第一项生成所有L、C和R定位ap
oStringFormat.Alignment = ?
oStringFormat.LineAlignment = ?
e.Graphics.DrawString(Me.Text, Me.Font, oBrush,
Rectangle.Inflate(ClientRectangle, 0, 0), oStringFormat)
End Using
End Using
End Sub
Using oStringFormat = New StringFormat() With
{.Alignment = StringAlignment.Center,
.LineAlignment = StringAlignment.Center}
'In order to see the Text property in the appearance section of the properties
'window, the Category attribute needs to be modified, which requires the
'inclusion of the ComponentModel namespace.
Imports System.ComponentModel
Public Class FlatButton
Inherits Button
...
End Class
Using oStringFormat = New StringFormat()
'There surely is a more concise way of doing this?
Select Case goTextAlign
Case ContentAlignment.TopLeft
oStringFormat.LineAlignment = StringAlignment.Near
oStringFormat.Alignment = StringAlignment.Near
Case ContentAlignment.TopCenter
oStringFormat.LineAlignment = StringAlignment.Near
oStringFormat.Alignment = StringAlignment.Center
Case ContentAlignment.TopRight
oStringFormat.LineAlignment = StringAlignment.Near
oStringFormat.Alignment = StringAlignment.Far
Case ContentAlignment.MiddleLeft
oStringFormat.LineAlignment = StringAlignment.Center
oStringFormat.Alignment = StringAlignment.Near
Case ContentAlignment.MiddleCenter
oStringFormat.LineAlignment = StringAlignment.Center
oStringFormat.Alignment = StringAlignment.Center
Case ContentAlignment.MiddleRight
oStringFormat.LineAlignment = StringAlignment.Center
oStringFormat.Alignment = StringAlignment.Far
Case ContentAlignment.BottomLeft
oStringFormat.LineAlignment = StringAlignment.Far
oStringFormat.Alignment = StringAlignment.Near
Case ContentAlignment.BottomCenter
oStringFormat.LineAlignment = StringAlignment.Far
oStringFormat.Alignment = StringAlignment.Center
Case ContentAlignment.BottomRight
oStringFormat.LineAlignment = StringAlignment.Far
oStringFormat.Alignment = StringAlignment.Far
End Select
'Draw the string contained in Text with the acquired brush in the
'acquired string format, in the button's client rectangle, which
'is enlarged by 3 pixels in each direction. The original client
'rectangle has a padding of 3 pixels to allow for a 2 pixels wide
'border (3D), and a 1-pixel margin between the border and the
'actual text.
e.Graphics.DrawString(Me.Text, Me.Font, oBrush,
Rectangle.Inflate(ClientRectangle, 3, 3), oStringFormat)
End Using 'Dispose the StringFormat object.
Console.WriteLine("-- ContentAlignment --")
For Each Name As String In [Enum].GetNames(GetType(System.Drawing.ContentAlignment))
Console.WriteLine(Name & ": " & CType([Enum].Parse(GetType(System.Drawing.ContentAlignment), Name), Integer))
Next
Console.WriteLine()
Console.WriteLine("-- StringAlignment --")
For Each Name As String In [Enum].GetNames(GetType(System.Drawing.StringAlignment))
Console.WriteLine(Name & ": " & CType([Enum].Parse(GetType(System.Drawing.StringAlignment), Name), Integer))
Next
Log(x Mod 5, 2)
'Horizontal version only. See the bottom of this answer for full code covering both horizontal and vertical.
Public Function ContentToStringAlignment(ByVal Alignment As ContentAlignment) As StringAlignment
Return CType(Math.Log(CType(Alignment, Integer) Mod 5, 2), StringAlignment)
End Function
Floor(Log(x, 16))
Public Function ContentToStringAlignment(ByVal Alignment As ContentAlignment, ByVal Vertical As Boolean) As StringAlignment
If Vertical = True Then Return CType(Math.Floor(Math.Log(CType(Alignment, Integer), 16)), StringAlignment)
Return CType(Math.Log(CType(Alignment, Integer) Mod 5, 2), StringAlignment)
End Function
oStringFormat.LineAlignment = ContentToStringAlignment(goTextAlign, True) 'True for vertical alignment.
oStringFormat.Alignment = ContentToStringAlignment(goTextAlign, False)
(StringAlignment)((((int)ca * 0x111) >> 9) & 0x3)
(StringAlignment)((((((int)ca * 7) & 0x444) * 0x49) >> 9) & 0x3)
(ContentAlignment)((0x111 << (int)ta) & (((((int)ca * 7) & 0x444) * 7) >> 2))
(ContentAlignment)((0x7 << (4 * (int)ta)) & (((((int)ca * 0x111) & 0x700) * 0x111) >> 8))