2011-06-13 31 views
19

Sử dụng các thành phần Delphi TRibbon chuẩn Tôi nhận thấy chúng không phải là rực rỡ.Tạo các ứng dụng theo kiểu Ribbon

  • Thứ nhất họ không đẹp như những người thân của Microsoft, ví dụ như các hiệu ứng ánh sáng và màu sắc trong TRibbon không trông ấn tượng như những người sử dụng trong Wordpad hoặc Paint trong Windows 7.

  • Thứ hai nếu bạn muốn tạo giao diện Ribbon theo kiểu, tôi nhận thấy rằng không có menu kiểu Ribbon hoặc menu popup độc lập với TRibbon. Đối với Ribbon thực tế có, nhưng nếu nói cho các mục đích liên tục bạn muốn các trình đơn popup kiểu Ribbon được gán cho một TListbox hoặc TListView ví dụ, có không xuất hiện là một.

  • Thứ ba, đôi khi khi Hành động Ribbon bị vô hiệu hóa, nó vẫn hiển thị hiệu ứng phát sáng nóng như thể di chuột qua Hành động, mặc dù nó bị tắt.

  • Cuối cùng tôi thấy rất khó khăn khi cố gắng đặt các thành phần vùng chứa như một hộp thư trong một nhóm. Việc định kích thước và vị trí điều khiển thực sự khó xử ...

Tôi đoán điểm của tôi là sử dụng các thành phần Delphi TRibbon chuẩn dường như không phải là cách tiếp cận tốt nhất cả trực quan và có ích. Làm thế nào tôi có thể làm cho một ứng dụng Ribbon theo kiểu dáng nhìn và làm việc gọn gàng như những người Microsoft làm giống như tôi đã nói trước cách Wordpad và Paint làm trong Windows 7?

Hãy nhìn vào ảnh chụp màn hình so sánh này để có được một ý tưởng tốt hơn:

enter image description here

Các Delphi Ribbon dường như không đầy đủ, trừ khi tôi đang mong đợi quá nhiều. Tôi tin rằng các thành phần Ribbon là để cung cấp ứng dụng của bạn với trải nghiệm tốt hơn cho người dùng cuối cả không gian làm việc trực quan và tốt hơn, v.v.

Bạn có thể đưa ra những đề xuất nào để làm việc và trông giống như Microsoft?

Tôi không sử dụng Giao diện kiểu Ribbon tất cả thời gian để mua Thành phần của bên thứ 3 không phải là thứ tôi thực sự muốn làm. Tôi đã xem xét các TMS và DevExpress nhưng đối với giá của họ, họ không nhìn tốt như một trong hai. Các TMS trông tồi tệ hơn Delphi TRibbon chuẩn.

+1

Bạn đã xem các phiên bản COM cung cấp bởi CÔ? Tôi nghĩ rằng họ sẽ là công việc khá khó khăn để sử dụng nhưng tôi chắc chắn rằng kết quả cuối cùng sẽ có chất lượng cao. –

+0

Theo như tôi biết, các thành phần băng Delphi là một phiên bản "ánh sáng" của DevExpress "ExpressBars". – Andreas

+0

Bạn có thể thử TMS Components (http://www.tmssoftware.com). Họ có thành phần Delphi Ribbon riêng của họ và các thành phần của họ rất hấp dẫn trực quan. Ngoài ra, bạn có thể có hiệu ứng Butoon ứng dụng (nút ứng dụng tăng cao hơn phụ đề) với điều kiện bạn tải xuống biểu mẫu chính của bạn từ một biểu mẫu cụ thể mà họ cung cấp. Nhìn vào bản demo để biết thêm thông tin. –

Trả lời

15

Để có giao diện bản địa, hãy kiểm tra Windows Ribbon Framework for Delphi.

Đây là trình bao bọc mã nguồn mở xung quanh the Windows Ribbon Framework có sẵn kể từ Windows 7 (và Vista sau khi cài đặt một số bản cập nhật chính thức). Đây là API được sử dụng bởi Windows 7 Word Pad.

Cũng lưu ý rằng bạn có hai loại bố cục: Office 2007 và Office 2010. VCBC Ribbon Delphi thực hiện kiểu Office 2007, trong khi Windows Seven WordPad sử dụng kiểu Office 2010.

Trong một số dự án của chúng tôi cho một số khách hàng, chúng tôi đã sử dụng TMS software Ribbon components. Mã này là một chút quá cỡ (rất nhiều bản sao hoặc các công cụ bằng văn bản xấu như thành phần kiên trì) nhưng nó hoạt động và làm tốt, hỗ trợ cả hai phong cách 2007 và 2010 Ribbon. Đối với khách hàng của chúng tôi, dựng hình là những gì quan trọng.Đối với khung nguồn mở của chúng tôi, we published a dual solution for building a Ribbon-like GUI, được tạo từ mã: nó sẽ sử dụng các thành phần VCL tiêu chuẩn cho bố cục cơ bản, hoặc thành phần TMS cho bản dựng Office 2007/2010 đầy đủ. Chúng tôi chỉ định nghĩa một số lớp, được thực hiện bởi một trong hai thư viện. Nếu bạn sử dụng các thành phần chung như được định nghĩa trong SQLite3ToolBar (tức là các lớp TSynForm, TSynToolBar, TSynToolButton, TSynPopupMenu, TSynPage, TSynPager, TSynBodyPagerTSynBodyPage) và SynTaskDialog (đối với TSynButton) trong mã của riêng bạn, USETMSPACK có điều kiện sẽ làm tất cả điều kỳ diệu cho bạn.

Chúng tôi chưa sử dụng thành phần Ribbon như đã được giới thiệu trong Delphi 2009. Thiết kế hướng hành động của nó sẽ không giúp dễ dàng giao tiếp với thiết kế hướng sự kiện của Giao diện người dùng của chúng tôi và chúng tôi phải thú nhận rằng thành phần này có danh tiếng khá xấu (ít nhất là trong phiên bản Delphi 2009).

Windows Ribbon Framework tuyệt vời cho Delphi sẽ không phù hợp với nhu cầu của chúng tôi về một Ribbon được tạo sẵn từ mã. Thiết kế của nó, từ chính bản thân Microsoft, là tạo ra giao diện người dùng từ một tài nguyên XML, được liên kết tại biên dịch ... vì vậy nó sẽ không phù hợp với nhu cầu của chúng ta, nhưng nó có thể phù hợp với bạn, để thiết kế giao diện ứng dụng "tĩnh" hơn.

Nếu bạn sử dụng Ribbon giống như Office trong ứng dụng của mình, hãy lưu ý đến số Office UI Licensing.

+0

"Mã nguồn sử dụng một số tính năng được giới thiệu trong Delphi 2010, chẳng hạn như công cụ RTTI mới. Vì vậy, bạn sẽ cần Delphi 2010 hoặc mới hơn để làm việc với thư viện này." Chỉ trích. –

+0

@Ian Có, nhưng đây là một thư viện rất tốt ... –

+0

@ A.Bouchez tôi đã chỉ perusing mã để xem có bao nhiêu tôi có thể cứu hộ - rất nhiều cấu trúc đã được thêm vào đối tượng Pascal kể từ phiên bản của Delphi mà tôi sử dụng. –

7

Câu trả lời thực dụng là sử dụng một bộ thành phần khác. Các TMS Software version appears good nhưng tôi sử dụng DevExpress ExpressBars một trong đó hoạt động rất tốt cho tôi.

+2

+1 cho thanh ghi nhanh DevExpress. Nếu bạn không thể làm điều đó với DevEx, nó có thể không được thực hiện. Nếu bạn muốn băng, hãy đi với DevEx. –

+0

có thể, nhưng như tôi đã nói, tôi không muốn mua bộ sản phẩm bên thứ 3. Băng TMS cũng trông tồi tệ hơn so với TRibbon chuẩn. –

+0

@Craig: nếu thời gian của bạn không đáng tiền, thì bạn luôn có thể thử sửa đổi băng VCL để tìm cách bạn muốn nó trông như thế nào. Tôi không tin rằng có bất kỳ băng nguồn mở nào, và trình bao bọc bằng cách sử dụng công cụ MS có nghĩa là bạn phụ thuộc vào các điều khiển MS .net không phải là một động thái dài hạn thông minh. Bạn sẽ hối tiếc ngày bạn xây dựng một sự phụ thuộc như vậy vào hệ thống của bạn. –

7

tôi sử dụng Windows Ribbon Framework - thành phần gốc đi kèm với Windows (7).

Đây là lớp lót siêu ngắn trên Khung Ribbon của Windows từ Delphi; sao chép-dán các phần quan trọng của mã, mà không cần giải thích nhiều:

procedure TfrmTicketDetail.ShowScenicRibbon; 
begin 
    try 
     Fframework := UIRibbon.CoUIRibbonFramework.Create; 
     Fframework.Initialize(Self.Handle, Self); //Give the ribbon the hwnd, and our implementation of uiapplication for callbacks 
     OleCheck(Fframework.LoadUI(hInstance, 'APPLICATION_RIBBON')); 
    except 
     on e:Exception do 
     begin 
      if DebugHook > 0 then 
       raise; 
      Exit; 
     end; 
    end; 
end; 

Nhưng nó bắt đầu bị lông, vì bạn phải tuân theo API của Microsoft.

{IUIApplication} 
function OnViewChanged(viewId: SYSUINT; typeID: UI_VIEWTYPE; const view: IUnknown; 
     verb: UI_VIEWVERB; uReasonCode: SYSINT): HResult; stdcall; 
function OnCreateUICommand(commandId: SYSUINT; typeID: UI_COMMANDTYPE; 
     out commandHandler: IUICommandHandler): HResult; stdcall; 
function OnDestroyUICommand(commandId: SYSUINT; typeID: UI_COMMANDTYPE; 
     const commandHandler: IUICommandHandler): HResult; stdcall; 

Và sau đó bạn phải thực hiện chúng:

function TfrmTicketDetail.OnViewChanged(viewId: SYSUINT; 
    typeID: UI_VIEWTYPE; const view: IUnknown; verb: UI_VIEWVERB; 
    uReasonCode: SYSINT): HResult; 
var 
    cy: integer; 
begin 
    Result := S_OK; 

    //viewID: The ID for the view. Only a value of zero is valid. 
    if viewID <> 0 then 
     Exit; 

    //typeID: The only declared typeID is UI_VIEWTYPE_RIBBON 
    if typeID <> UI_VIEWTYPE_RIBBON then 
     Exit; 

    case verb of //there are only 4 verbs: create, destroy, size, error 
    UI_VIEWVERB_CREATE: 
     begin 
      { The view was resized. 
       In the case of the Ribbon view, the application should call 
       GetHeight() to determine the height of the Ribbon.} 
      (view as IUIRibbon).GetHeight(cy); 
      bvTopSpacer.Height := cy; 
     end; 
    UI_VIEWVERB_SIZE: 
     begin 
      { The view was resized. 
       In the case of the Ribbon view, the application should call 
       GetHeight() to determine the height of the Ribbon.} 
      (view as IUIRibbon).GetHeight(cy); 
      bvTopSpacer.Height := cy; 
     end; 
    UI_VIEWVERB_DESTROY: {nop}; 
    UI_VIEWVERB_ERROR: {nop}; 
    end; 

    Result := S_OK; 
end; 

function TfrmTicketDetail.OnCreateUICommand(commandId: SYSUINT; 
    typeID: UI_COMMANDTYPE; out commandHandler: IUICommandHandler): HResult; 
begin 
    commandHandler := Self; //this form will handle all commands on the ribbon; 
    Result := S_OK; 
end; 

function TfrmTicketDetail.OnDestroyUICommand(commandId: SYSUINT; typeID: UI_COMMANDTYPE; 
     const commandHandler: IUICommandHandler): HResult; 
begin 
    Result := E_NOTIMPL; 
end; 

Và sau đó bạn cũng phải

  • thực hiện IUICommandHandler
  • tác giả một tập tin băng XML
  • biên dịch ruy băng Tệp XML với trình biên dịch ribbon
  • bao gồm các băng biên soạn như một nguồn lực:

    {$RESOURCE '..\Resource\UIRibbon\Ribbon_frmTicketDetails.res'}

Dưới đây là một bãi chứa của xml băng tôi có cho ứng dụng của tôi:

<?xml version="1.0" encoding="utf-8"?> 
<Application xmlns="http://schemas.microsoft.com/windows/2009/Ribbon"> 

    <!-- Commands are like actions, with a name, a numeric ID, caption (LabelTitle), Large and Small images, etc --> 
    <Application.Commands> 
     <Command Name="cmdNew" Id="0xE100" Symbol="ID_CMD_NEW" LabelTitle="New document" /> 
     <Command Name="cmdSaveAs" Id="0xE102" Symbol="ID_CMD_SAVEAS" LabelTitle="Save as" /> 
     <Command Name="cmdOpen" Id="0xE103" Symbol="ID_CMD_OPEN" LabelTitle="Open" /> 
     <Command Name="cmdExit" Id="0xE104" Symbol="ID_CMD_EXIT" LabelTitle="Exit" /> 
     <Command Name="cmdUndo" Id="0xE105" Symbol="ID_CMD_UNDO" LabelTitle="Undo" /> 

     <Command Name="cmdCut" Id="0xE110" Symbol="ID_CMD_CUT" LabelTitle="Cut" /> 
     <Command Name="cmdCopy" Id="0xE111" Symbol="ID_CMD_COPY" LabelTitle="Copy" /> 
     <Command Name="cmdPaste" Id="0xE112" Symbol="ID_CMD_PASTE" LabelTitle="Paste" /> 
     <Command Name="cmdDelete" Id="0xE113" Symbol="ID_CMD_DELETE" LabelTitle="Delete" /> 
     <Command Name="cmdZoom" Id="0xE114" Symbol="ID_CMD_ZOOM" LabelTitle="Zoom" /> 

     <Command Name="tabHome" LabelTitle="Home" /> 

      <Command Name="grpActions" LabelTitle="Actions" /> 
       <Command Name="cmdSaveAndClose" Id="1101" Symbol="ID_ACTION_SAVEANDCLOSE" LabelTitle="Save and Close"> 
        <Command.TooltipTitle>Save and Close (Alt+S)</Command.TooltipTitle> 
        <Command.TooltipDescription>Saves the current ticket and closes the detail screen.</Command.TooltipDescription> 
        <Command.LargeImages> 
         <Image Source="SaveAndClose.bmp" /> 
        </Command.LargeImages> 
       </Command> 
       <Command Name="cmdBack" Id="1102" LabelTitle="Back" /> 
       <Command Name="cmdControlPanel" Id="1103" LabelTitle="Control Panel" /> 
       <Command Name="cmdSave" Id="1104" LabelTitle="Save" /> 

      <Command Name="grpShow" Id="1201" LabelTitle="Show" /> 
       <Command Name="cmdShowTicket" Id="1202" LabelTitle="Ticket" ></Command> 
       <Command Name="cmdShowDiaryEntries" Id="1203" LabelTitle="Diary Entries" > 
        <Command.LargeImages> 
         <Image Source="PencilLog_32x32.bmp" /> 
        </Command.LargeImages> 
       </Command> 
       <Command Name="cmdShowAttachments" Id="1204" LabelTitle="Attachments" /> 
       <Command Name="cmdShowAuditLog" Id="1205" LabelTitle="Audit Log" /> 
       <Command Name="cmdShowAdditional" Id="1206" LabelTitle="Additional" /> 

      <Command Name="grpActivity" LabelTitle="Activity" /> 
       <Command Name="cmdStartWorking" Id="1301" LabelTitle="Start Working"></Command> 
       <Command Name="cmdStopWorking" Id="1302" LabelTitle="Stop Working"></Command> 
       <Command Name="cmdPrint" Id="1303" LabelTitle="Print" > 
        <Command.LargeImages> 
         <Image Source="Printer - 256x256.bmp" /> 
        </Command.LargeImages> 
        <Command.SmallImages> 
         <Image Source="Printer_16x16.bmp" /> 
        </Command.SmallImages> 
       </Command> 
       <Command Name="cmdDuplicateTicket" Id="1304" LabelTitle="Duplicate Ticket" > 
        <Command.SmallImages> 
         <Image Source="DuplicateTicket16.bmp" /> 
        </Command.SmallImages> 
       </Command> 

      <Command Name="grpTicketStatus" LabelTitle="Ticket Status" /> 
       <Command Name="cmdCloseTicket" Id="1402" LabelTitle="Close Ticket" /> 
       <Command Name="cmdOnHold" Id="1403" LabelTitle="On Hold" /> 
       <Command Name="cmdReadyForInstall" Id="1404" LabelTitle="Ready for install" /> 
       <Command Name="cmdReopenTicket" Id="1405" LabelTitle="Reopen Ticket" /> 

    </Application.Commands> 

    <!-- Above is all the commands (i.e. Actions). Now we get to the tool on screen (i.e. a DFM) --> 
    <Application.Views> 
     <Ribbon> 

      <!-- Items that appear under the "round button" menu --> 
      <Ribbon.ApplicationMenu> 
       <ApplicationMenu CommandName="cmdFileMenu"> 
        <MenuGroup> 
         <Button CommandName="cmdNew" /> 
         <Button CommandName="cmdOpen" /> 
         <Button CommandName="cmdSave" /> 
         <Button CommandName="cmdSaveAs" /> 
        </MenuGroup> 
        <MenuGroup> 
         <Button CommandName="cmdExit" /> 
        </MenuGroup> 
       </ApplicationMenu> 
      </Ribbon.ApplicationMenu> 

      <!--What commands to add to the quick access toolbar 
        Right now only Save and Undo, just for fun--> 
      <Ribbon.QuickAccessToolbar> 
       <QuickAccessToolbar> 
        <QuickAccessToolbar.ApplicationDefaults> 
         <Button CommandName="cmdSave" /> 
         <Button CommandName="cmdUndo" /> 
        </QuickAccessToolbar.ApplicationDefaults> 
       </QuickAccessToolbar> 
      </Ribbon.QuickAccessToolbar> 

      <!-- And now finally the actual tabs --> 
      <Ribbon.Tabs> 
       <!--Our one and only tab is "Home" --> 
       <Tab CommandName="tabHome"> 
        <Tab.ScalingPolicy> 
         <ScalingPolicy> 
          <ScalingPolicy.IdealSizes> 
           <Scale Group="grpActions" Size="Medium"/> 
           <Scale Group="grpShow" Size="Medium"/> 
           <Scale Group="grpActivity" Size="Medium"/> 
           <Scale Group="grpTicketStatus" Size="Medium"/> 
          </ScalingPolicy.IdealSizes> 
          <Scale Group="grpActions" Size="Small"/> 
          <Scale Group="grpShow" Size="Small"/> 
          <Scale Group="grpActivity" Size="Small"/> 
          <Scale Group="grpTicketStatus" Size="Small"/> 
         </ScalingPolicy> 
        </Tab.ScalingPolicy> 

        <!-- Home\Actions --> 
        <Group CommandName="grpActions" SizeDefinition="FourButtons"> 
         <Button CommandName="cmdSaveAndClose" /> 
         <Button CommandName="cmdBack" /> 
         <Button CommandName="cmdControlPanel" /> 
         <Button CommandName="cmdSave" /> 
        </Group> 

        <!-- Home\Show group --> 
        <Group CommandName="grpShow" SizeDefinition="FiveButtons"> 
         <ToggleButton CommandName="cmdShowTicket" /> 
         <ToggleButton CommandName="cmdShowDiaryEntries" /> 
         <ToggleButton CommandName="cmdShowAttachments" /> 
         <ToggleButton CommandName="cmdShowAuditLog" /> 
         <ToggleButton CommandName="cmdShowAdditional" /> 
        </Group> 

        <!-- Home\Activity group, with a custom sizing definition 
          so i get my "FourButtons-TwoBigTwoSmall" look --> 
        <Group CommandName="grpActivity" > 
         <SizeDefinition> 
          <ControlNameMap> 
           <ControlNameDefinition Name="button1"/> 
           <ControlNameDefinition Name="button2"/> 
           <ControlNameDefinition Name="button3"/> 
           <ControlNameDefinition Name="button4"/> 
          </ControlNameMap> 
          <GroupSizeDefinition Size="Large"> 
           <ControlSizeDefinition ControlName="button1" ImageSize="Large" IsLabelVisible="true" /> 
           <ControlSizeDefinition ControlName="button2" ImageSize="Large" IsLabelVisible="true" /> 
           <ColumnBreak ShowSeparator="true"/> 
           <ControlSizeDefinition ControlName="button3" ImageSize="Large" IsLabelVisible="true" /> 
           <ControlSizeDefinition ControlName="button4" ImageSize="Large" IsLabelVisible="true" /> 
          </GroupSizeDefinition> 
          <GroupSizeDefinition Size="Medium"> 
           <ControlSizeDefinition ControlName="button1" ImageSize="Large" IsLabelVisible="true" /> 
           <ControlSizeDefinition ControlName="button2" ImageSize="Large" IsLabelVisible="true" /> 
           <ColumnBreak ShowSeparator="true"/> 
           <Row> 
            <ControlSizeDefinition ControlName="button3" ImageSize="Small" IsLabelVisible="true" /> 
           </Row> 
           <Row> 
            <ControlSizeDefinition ControlName="button4" ImageSize="Small" IsLabelVisible="true" /> 
           </Row> 
          </GroupSizeDefinition> 
          <GroupSizeDefinition Size="Small"> 
           <Row> 
            <ControlSizeDefinition ControlName="button1" ImageSize="Small" IsLabelVisible="true" /> 
            <ControlSizeDefinition ControlName="button3" ImageSize="Small" IsLabelVisible="false" /> 
           </Row> 
           <Row> 
            <ControlSizeDefinition ControlName="button2" ImageSize="Small" IsLabelVisible="true" /> 
            <ControlSizeDefinition ControlName="button4" ImageSize="Small" IsLabelVisible="false" /> 
           </Row> 
          </GroupSizeDefinition> 
         </SizeDefinition> 

         <Button CommandName="cmdStartWorking" /> 
         <Button CommandName="cmdStopWorking" /> 
         <Button CommandName="cmdPrint" /> 
         <Button CommandName="cmdDuplicateTicket" /> 
        </Group> 

        <!-- Home\Ticket Status group --> 
        <Group CommandName="grpTicketStatus" SizeDefinition="FourButtons"> 
         <Button CommandName="cmdCloseTicket" /> 
         <Button CommandName="cmdOnHold" /> 
         <Button CommandName="cmdReadyForInstall" /> 
         <Button CommandName="cmdReopenTicket" /> 
        </Group> 
       </Tab> 
      </Ribbon.Tabs> 
      <!-- End of the actual tabs --> 

     </Ribbon> 
    </Application.Views> 
</Application> 
+2

Tốt hơn nhiều khi sử dụng thành phần Delphi kết thúc tốt đẹp, như được gợi ý bởi @ A.Bouchez –

+0

wow trông giống như rất nhiều nỗ lực, nhưng cảm ơn bạn đã chia sẻ nó thú vị khi thấy mã đó. –

+1

+1 để đặt thông tin tuyệt vời trên StackOverflow, mặc dù tôi đồng ý với David về việc sử dụng trình bao bọc đã được kiểm tra đơn vị @ABouchez đề xuất –

Các vấn đề liên quan