PDA

View Full Version : گفتگو: استفاده از ResourceManager برای فراخوانی آیتمهای ریسورس پروژه اصلی



ROSTAM2
سه شنبه 29 آذر 1401, 21:49 عصر
سلام.

من یک Component سفارشی دارم که با استفاده از کلاس ResourceManger رشته رو از ریسورس تعیین شده در خصوصیت Resource از Component برای یک StatusLabel با رفتن ماوس روی اشیاء فراهم می کنه:

154378

154377
154381
154379

این هم سورسش توی پروژه اصلی:


Imports System.ComponentModel
Imports System.Resources
Imports System.Reflection
Imports System.Threading
Imports System.Globalization
<ProvideProperty("Status", GetType(Control))> _
Public Class StatusProvider
Implements IExtenderProvider


Private WithEvents StatusLabelValue As ToolStripLabel
Public Property StatusLabel() As ToolStripLabel
Get
Return StatusLabelValue
End Get
Set(ByVal value As ToolStripLabel)
StatusLabelValue = value
End Set
End Property
Private Shared resourceMan As Global.System.Resources.ResourceManager
'''<summary>
''' Returns the cached ResourceManager instance used by this class.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttrib ute(Global.System.ComponentModel.EditorBrowsableSt ate.Advanced)> _
Friend Shared ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim ResourceName As String = String.Format("{0}.{1}", My.Application.Info.AssemblyName, ResourceValue)
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager(ResourceNa me, GetType(StatusProvider).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
Private Shared ResourceValue As String = "Resources"
<Description("Resources"), DefaultValue("Resources")> _
Public Property Resource() As String
Get
Return ResourceValue
End Get
Set(ByVal value As String)
ResourceValue = value
End Set
End Property
Protected StatusControls As New Dictionary(Of Control, String)
Public Sub SetStatus(Ctl As Control, Value As String)
If Me.StatusControls.ContainsKey(Ctl) = False Then
Me.StatusControls.Add(Ctl, Value)
AddHandler Ctl.MouseEnter, AddressOf _MouseEnter
AddHandler Ctl.MouseLeave, AddressOf _MouseLeave
Else
If Value = String.Empty Then
Me.StatusControls.Remove(Ctl)
RemoveHandler Ctl.MouseEnter, AddressOf _MouseEnter
RemoveHandler Ctl.MouseLeave, AddressOf _MouseLeave
Exit Sub
End If
Me.StatusControls(Ctl) = Value
End If
End Sub
<Description("String Name in Resource. (@<ResName>)")> _
Public Function GetStatus(Ctl As Control) As String
If Me.StatusControls.ContainsKey(Ctl) = True Then
Return Me.StatusControls(Ctl)
Else
Return ""
End If
End Function


Public Function CanExtend(extendee As Object) As Boolean Implements System.ComponentModel.IExtenderProvider.CanExtend
Return TypeOf extendee Is Control
End Function
Private Sub _MouseEnter(sender As Object, e As System.EventArgs)
If Me.StatusLabel Is Nothing Then Exit Sub
Dim Expr As String = Me.StatusControls(sender)
If Expr.StartsWith("@") Then
Me.StatusLabel.Text = ResourceManager.GetString(Expr.Remove(0, 1))
Else
Me.StatusLabel.Text = Expr
End If
End Sub

Private Sub _MouseHover(sender As Object, e As System.EventArgs)

End Sub

Private Sub _MouseLeave(sender As Object, e As System.EventArgs)
If Me.StatusLabel Is Nothing Then Exit Sub
Me.StatusLabel.Text = String.Empty
End Sub

Private Sub StatusProvider_Disposed(sender As Object, e As System.EventArgs) Handles Me.Disposed
For Each ctl As Control In Me.StatusControls.Keys
RemoveHandler ctl.MouseEnter, AddressOf _MouseEnter
RemoveHandler ctl.MouseLeave, AddressOf _MouseLeave
Next
End Sub
End Class


154380

سوال: من اگر بخوام این کامپوننت رو در یک پروژه Class Library ایجاد کنم برای استفاده در پروژه های دیگر چطور می تونم به ریسورس موجود در پروژه هدف دسترسی داشته باشم؟!

ROSTAM2
چهارشنبه 30 آذر 1401, 18:33 عصر
به نام خدا
سلام مجدد.
برای ایجاد این کامپوننت در یک پروژه Class Library و اشتراک آن در پروژه های دیگر من این روش رو استفاده کردم اگر روش بهتری سراغ دارید حتما در همین تاپیک اعلام کنید:


یک خصوصیت Assembly به کامپوننت اضافه:
Private AssemblyValue As Reflection.Assembly = Nothing <Browsable(False)> _
Public Overridable ReadOnly Property Assembly() As System.Reflection.Assembly
Get
Return AssemblyValue
End Get
End Property
در خصوصیت ResourceManager برای پارامتر دوم ResourceManager یک Assembly که باید Assembly پروژه باشه استفاده بشه تا ریسورس های داخل همون پروژه شناسایی بشه.

Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
If Assembly Is Nothing Then
resourceMan = My.Resources.ResourceManager
Else
Dim ResourceName As String = String.Format("{0}.{1}", My.Application.Info.AssemblyName, Me.ResourceValue)
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager(ResourceNa me, Assembly)
resourceMan = temp
End If
End If
Return resourceMan
End Get
End Property

IsupportInitialize Interface رو به کامپوننت اضافه:

Implements ISupportInitialize

در متود EndInit از اون این دستور رو بکار می بریم تا Assembly پروژه اصلی شناسایی بشه:

Public Sub EndInit() Implements System.ComponentModel.ISupportInitialize.EndInit
If Me.Site.DesignMode = True Then Exit Sub
For Each CTL As Control In Me.StatusTextControls.Keys
If TypeOf CTL Is Form Then
Me.AssemblyValue = CType(CTL, Form).GetType.Assembly
Exit For
Else
If TypeOf CTL.TopLevelControl Is Form Then
Me.AssemblyValue = CType(CTL.TopLevelControl, Form).GetType.Assembly
Exit For
End If
End If
Next
End Sub


حالا اگر Component رو در پروژه ای دیگر استفاده کنیم ریسورس های موجود در همون پروژه رو شناسایی خواهد کرد.

ROSTAM2
پنج شنبه 01 دی 1401, 18:41 عصر
سلام مجدد.
برای بدست آوردن فرمی که کامپوننت در اون قرار داره و برای گرفتن assembly پروژه از این دستورات در EndInit استفاده می شد:

Public Sub EndInit() Implements System.ComponentModel.ISupportInitialize.EndInit
If Me.Site.DesignMode = True Then Exit Sub
For Each CTL As Control In Me.StatusTextControls.Keys
If TypeOf CTL Is Form Then
Me.AssemblyValue = CType(CTL, Form).GetType.Assembly
Exit For
Else
If TypeOf CTL.TopLevelControl Is Form Then
Me.AssemblyValue = CType(CTL.TopLevelControl, Form).GetType.Assembly
Exit For
End If
End If
Next
End Sub


از سرویس IDesignerHost هم نمی شه استفاه کرد چون فقط در زمان Design جواب می ده یا شاید من بلد نیستم.

ولی من از یک ProvideProperty که Browsable از اون False هست و Type اون Form هست استفاده کردم و سریع و راحت جواب می ده:

ProvideProperty("Assembly", GetType(Form))


این هم متودهای اون ProvideProperty:

Protected AssemblyControls As New Dictionary(Of Control, String)
Public Sub SetAssembly(Ctl As Form, Value As String)
If AssemblyControls.ContainsKey(Ctl) = False Then
AssemblyControls.Add(Ctl, Value)
Else
AssemblyControls(Ctl) = Value
End If
Me.AssemblyValue = Ctl.GetType.Assembly
End Sub
<Browsable(False)> _
<DesignerSerializationVisibility(DesignerSerializat ionVisibility.Visible)> _
Public Function GetAssembly(ctl As Form) As String
If AssemblyControls.ContainsKey(ctl) = False Then
Return ""
End If
Return AssemblyControls(ctl)
End Function


همچنین از این طریق می شه به Form برای استفاده در کامپوننت دسترسی داشت.

پرستو پارسایی
دوشنبه 28 فروردین 1402, 21:57 عصر
به نظرم
برای دسترسی به ریسورس های موجود در پروژه هدف، می توانید از کد زیر برای ایجاد یک شیء از کلاس ResourceManager استفاده کنید:

Dim rm As New ResourceManager("Namespace.ResourceName", GetType(StatusProvider).Assembly)

در اینجا ، "Namespace" باید نام فضای نامی باشد که ریسورس ها در آن قرار دارند و "ResourceName" نام فایل ریسورس است. با استفاده از شیء ResourceManage می توانید به ریسورس های موجود در پروژه دسترسی پیدا کنید. سپس می توانید این شیء را به عنوان ورودی به کلاس StatusProvider ارسال کنید تا بتوانید از ریسورس ها در کد خود استفاده کنید. برای مثال، می توانید خطوط زیر را به کد کلاس StatusProvider اضافه کنید:

Private Shared resourceMan As Global.System.Resources.ResourceManager...
Private Sub New()
resourceMan = New ResourceManager("Namespace.ResourceName", GetType(StatusProvider).Assembly)
End Sub
...
Private Sub _MouseEnter(sender As Object, e As System.EventArgs)
If Me.StatusLabel Is Nothing Then Exit Sub
Dim Expr As String = Me.StatusControls(sender)
If Expr.StartsWith("@") Then
Me.StatusLabel.Text = resourceMan.GetString(Expr.Remove(0, 1))
Else
Me.StatusLabel.Text = Expr
End If

End Sub

saeidmobashery
جمعه 18 اسفند 1402, 09:26 صبح
به نظرم
برای دسترسی به ریسورس های موجود در پروژه هدف، می توانید از کد زیر برای ایجاد یک شیء از کلاس ResourceManager استفاده کنید:

Dim rm As New ResourceManager("Namespace.ResourceName", GetType(StatusProvider).Assembly)

در اینجا ، "Namespace" باید نام فضای نامی باشد که ریسورس ها در آن قرار دارند و "ResourceName" نام فایل ریسورس است. با استفاده از شیء ResourceManage می توانید به ریسورس های موجود در پروژه دسترسی پیدا کنید. سپس می توانید این شیء را به عنوان ورودی به کلاس StatusProvider ارسال کنید تا بتوانید از ریسورس ها در کد خود استفاده کنید. برای مثال، می توانید خطوط زیر را به کد کلاس StatusProvider اضافه کنید:

Private Shared resourceMan As Global.System.Resources.ResourceManager...
Private Sub New()
resourceMan = New ResourceManager("Namespace.ResourceName", GetType(StatusProvider).Assembly)
End Sub
...
Private Sub _MouseEnter(sender As Object, e As System.EventArgs)
If Me.StatusLabel Is Nothing Then Exit Sub
Dim Expr As String = Me.StatusControls(sender)
If Expr.StartsWith("@") Then
Me.StatusLabel.Text = resourceMan.GetString(Expr.Remove(0, 1))
Else
Me.StatusLabel.Text = Expr
End If

End Sub




استاد عزیز سلام و عرض ارادت ، من یک فایل DLL که مربوط به یک کتابخانه است به ریسورس اضافه کردم ولی نمی‌دانم به چه صورتی در سابروتین مورد نظرم آن را فراخوانی کنم

ROSTAM2
شنبه 11 فروردین 1403, 15:42 عصر
برای صدا زدن یک ریسورس از ریسورس های پروژه مقصد در یک پروژه کتابخانه خصوصیت ResourceManager:


Friend ReadOnly Property ResourceManager(ResourcesName As String) As Global.System.Resources.ResourceManager
Get
Dim ResourceName As String = String.Format("{0}.{1}", My.Application.Info.AssemblyName, ResourcesName)
Return New Global.System.Resources.ResourceManager(ResourceNa me, Assembly.GetEntryAssembly)
End Get
End Property


دریافت مقدار ریسورس رشته ای:

Expr = ResourceManager(<ResourcesName>).GetString(<ResourceName>)


برای نمونه <ResourcesName> می تونه Resources بصورت متنی باشه
و <ResourceName> نام ریسورس مثلا Strring1

در نمونه ای که من دارم یک پروژه Control Library هست که یک خصوصیت Provider داره که مقدار خصوصیت متکل از نام فایل Resources و نام Resource باید باشه به این شکل:

@<ResourcesName>, <ResourceName>


155537

155538

ROSTAM2
یک شنبه 26 فروردین 1403, 11:36 صبح
استاد عزیز سلام و عرض ارادت ، من یک فایل DLL که مربوط به یک کتابخانه است به ریسورس اضافه کردم ولی نمی‌دانم به چه صورتی در سابروتین مورد نظرم آن را فراخوانی کنم

من این سوال رو چندین بار خوندم تا الآن متوجه شدم که شما یک فایل DLL رو به ریسورس اضافه کردید!!!!

برای استفاده از یک Library یا Reference یا مرجع باید آنرا به بخش References از پروژه اضافه کنید:

155594

155595

155596