فرم های Worksheet با استفاده ازمعماری Style درWPF

سه شنبه 25 آبان 1395

زمانی که روی UI و UX یک پروژه کار میکنید ممکن است با مشکلاتی مواجه شوید که این Framework در حل آن مشکلات به شما کمک خواهد کرد . در این مقاله ، برای ایجاد و نگهداری راحت ترِ فرم های Excel-WorkSheet نکاتی را برای شما شرح خواهیم داد .

فرم های Worksheet با استفاده ازمعماری Style درWPF

معرفی : 

1. به واقع ، maintainability کدهای ما را افزایش میدهد . 
2. هم در کد و هم در قسمت گرافیکی باید Scalable باشند . 
3. برای استفاده باید ساده و روان باشند . 

در اخر ، ما این عقیده را داریم که این framework ، با محدودیت های محیط ، یک نقطه شروع خوب برای حل این دست از مشکلات میباشد . 

حال به سراغ کد می رویم :

مرور : 
برای فهم بهتر ، بهتر است که آشنایی با فایل های Excel داشته باشید ، به این دلیل که ما در این مقاله توضیح مفصلی درباره این موضوع نخواهیم داشت و فقط بیان میکنیم و از آن رد می شویم . 

Buttons :
[Hit it with wrench] - فعال کردن مجدد ترسیم (drawing) بر روی صفحه . از زمانی که drawing غیرفعال میشود این فقط به عنوان یک ویژگی in-dev در نظر گرفته میشود 

[<] و [>] - حلقه ی هفته ها ، متناوبا شما میتوانید اعداد جاری را تایپ کرده و کلید tab یا enter را بزنید . 
[>] = هفته قبل ؛ [<]=هفته بعد 

[Settings] - یک فرم برای تنظیمات عمومی و نگهداری کارمندان باز خواهد کرد . 


Classها :

در این جا دو کلاس اصلی وجود دارد - CellView و TemplateView . دومین کلاس ، این به عنوان یک کلاس الگو مورد استفاده قرار میگیرد و به خودیِ خود هیچ کاری انجام نمیدهد . در ادامه این مقاله به بررسی این کلاس خواهیم پرداخت . 
اولین کلاس ، CellView ، فعل و انفعالات با یک single cell را تسهیل میبخشد . این یک شی  بسیار سبک است که شامل یکسری single Range object برای اشاره به یک cell مشخص و دسترسی دهندههای مشخصه ( property accessors) ، مورد استفاده قرار میگیرد . 

برای روشن تر شدن قضیه : 
اشاره به روابط Parent/Child بین اشیا کاملا در یک جهت سلسه مراتبی میباشد ، نه در جهت polymorphic . 

CellView :

Private pRg As Range

' Gets/Sets cell this object points to
Public Property Get Pos() As Range
    Set Pos = pRg
End Property
Public Property Let Pos(Value As Range)
    Set pRg = Value
End Property

Private Function IsInit() As Boolean
    IsInit = (Not pRg Is Nothing)
End Function

...

' Value
Public Property Get Value() As String
    If IsInit Then
        Value = Pos.Value
    End If
End Property
Public Property Let Value(val As String)
    If IsInit Then
        Pos.Value = val
    End If
End Property

' Text
Public Property Get Text() As String
    If IsInit Then
        Text = Pos.Text
    End If
End Property

' Address
Public Property Get Address() As String
    If IsInit Then
        Address = Pos.Address
    End If
End Property

مثال - EmpTtlView :

مثال زیر ، چگونگی استفاده بهتر ازاین کلاس را نمایش میدهد. توجه داشته باشید که EmpTtlView از TemplateView ، که بیش تر آن را معرفی کردیم ، کپی شده است .

'
' EmpTtlView - Handles I/O and formatting for a single employee's daily totals.
'

' <Other Declarations>

...

' Properties
Public TimeWk As CellView
Public GoalWk As CellView
Public SalesWk As CellView
Public OverUnderWk As CellView

Public TimeYTD As CellView
Public GoalYTD As CellView
Public SalesYTD As CellView
Public OverUnderYTD As CellView

Public TimeLbl As CellView
Public GoalLbl As CellView
Public SalesLbl As CellView
Public OverUnderLbl As CellView

...

' Initialization...

Public Function Init(parentView As EmpView)
    If Not pInit Then
        Set pParentView = parentView
        Set pSett = Singletons.GetSettings
        
        pViewWidth = 1
        pViewHeight = 1
        
        Set TimeWk = New CellView
        Set GoalWk = New CellView
        ...
'...end Function Init

...

' Function SetPosition...

        Set pRg = rgPosition.Cells(1, 1)
        ' columns
        wk = 1
        ytd = 2
        lbl = 3
        'rows
        hrs = 1
        gls = 2
        sls = 3
        ou = 4
        
        TimeWk.Pos = pRg.Cells(hrs, wk)
        GoalWk.Pos = pRg.Cells(gls, wk)
        SalesWk.Pos = pRg.Cells(sls, wk)
        OverUnderWk.Pos = pRg.Cells(ou, wk)
        
        TimeYTD.Pos = pRg.Cells(hrs, ytd)
        GoalYTD.Pos = pRg.Cells(gls, ytd)
        SalesYTD.Pos = pRg.Cells(sls, ytd)
        OverUnderYTD.Pos = pRg.Cells(ou, ytd)
        
        TimeLbl.Pos = pRg.Cells(hrs, lbl)
        GoalLbl.Pos = pRg.Cells(gls, lbl)
        SalesLbl.Pos = pRg.Cells(sls, lbl)
        OverUnderLbl.Pos = pRg.Cells(ou, lbl)

' ...end Function SetPosition

...

'----[ Utils ]----------------------------------------------------
Private Function AppendFormula(rgCell As Range, firstStr As String, appendStr As String)
    If Not rgCell Is Nothing Then
        If rgCell.Formula <> "" Then
            rgCell.Formula = Mid(rgCell.Formula, 1, Len(rgCell.Formula) - 1) & ", " & appendStr & ")"
        Else
            rgCell.Formula = firstStr
        End If
    End If
End Function

...

' Some simple automated formula creation...
Public Function CalcSales(rgSales As String)
    If IsInit Then
        AppendFormula SalesWk.Pos, "=SUM(" & rgSales & ")", rgSales
    End If
End Function

Public Function CalcOverUnder()
    If IsInit Then
        OverUnderWk.Formula = "=" & GoalWk.Address & "-" & SalesWk.Address
    End If
End Function

...


TemplateView :

اشیا TemplateView برای تعیین جای سلسه مراتب و مقیاس پذیری برای کار کردن ، نیاز به اعمال دستی یکسری تغییرات دارند . فقط این جنبه از TemplateView را پوشش خواهیم داد .

Viewها ، parent viewها و فرزندان خود را میشناسند و به آن ها نیز ارجاعی دارند 

' Replace 'Variant' with actual parent class
Private pParentView As Variant

' Add child(ren) references here...

Private pSett As Settings

' position relative to parent
Private pRg As Range

Private pViewWidth As Integer
Private pViewHeight As Integer

Private pInit As Boolean

...

' TODO: replace 'Variant' with actual parent class
Public Function Init(parentView As Variant)
    If Not pInit Then
        Set pParentView = parentView
        Set pSett = Singletons.GetSettings
        
        pViewWidth = 1
        pViewHeight = 1
    End If
    pInit = True
End Function

'----[ Position ]---------------------------------------------
' SetPosition usage - used from 'pParentView'; usage snippet:
'
'        ' array of "day" views (children)
'        Private pDayViews(6) As DayView
'
'        ' simple day counter
'        Dim d As Integer
'
'        ' Set position of template view to the first cell of the position arg
'        Set pRg = rgPosition.Cells(1, 1)
'
'        ' <init/populate pDayViews & other logic>
'
'        ' for each day of the week, graphically append each day's view so none overlap
'        For d = 0 To 6
'            '            <first row>, <next empty/avail column>
'            '                         <current pos> + <this view's width> + <DayView width * day count>
'            pDayViews(d).SetPosition pRg.Cells(1, 1 + pViewWidth + pDayViews(d).OffsetWidth(d))
'        Next d
'
' rgPosition is the upper-left most cell of this view
Public Function SetPosition(rgPosition As Range)
    If pInit And (Not rgPosition Is Nothing) Then
        ' Range.Cells(1) lets us not care about merged cells/ranges
        Set pRg = rgPosition.Cells(1, 1)
    End If
End Function

' Returns this view's width multiplied by offsetIndex.
Public Function OffsetWidth(offsetIndex As Integer) As Integer
    If IsInit Then
        OffsetWidth = pViewWidth * offsetIndex
    End If
End Function

' Returns this view's height multiplied by offsetIndex.
Public Function OffsetHeight(offsetIndex As Integer) As Integer
    If IsInit Then
        OffsetHeight = pViewHeight * offsetIndex
    End If
End Function

-

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان
  • WPF
  • 2k بازدید
  • 1 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید