国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[MAUI]在.NET MAUI中實(shí)現(xiàn)可拖拽排序列表

這篇具有很好參考價(jià)值的文章主要介紹了[MAUI]在.NET MAUI中實(shí)現(xiàn)可拖拽排序列表。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


.NET MAUI 中提供了拖放(drag-drop)手勢(shì)識(shí)別器,允許用戶通過(guò)拖動(dòng)手勢(shì)來(lái)移動(dòng)控件。在這篇文章中,我們將學(xué)習(xí)如何使用拖放手勢(shì)識(shí)別器來(lái)實(shí)現(xiàn)可拖拽排序列表。在本例中,列表中顯示不同大小的磁貼(Tile)并且可以拖拽排序。

[MAUI]在.NET MAUI中實(shí)現(xiàn)可拖拽排序列表,.NET MAUI,產(chǎn)品設(shè)計(jì),.net,xamarin

使用.NET MAU實(shí)現(xiàn)跨平臺(tái)支持,本項(xiàng)目可運(yùn)行于Android、iOS平臺(tái)。

創(chuàng)建可拖放控件

新建.NET MAUI項(xiàng)目,命名Tile

當(dāng)手指觸碰可拖拽區(qū)域超過(guò)一定時(shí)長(zhǎng)(不同平臺(tái)下時(shí)長(zhǎng)不一定相同,如在Android中是1s)時(shí),將觸發(fā)拖動(dòng)手勢(shì)。
手指離開(kāi)屏幕時(shí),將觸發(fā)放置手勢(shì)。

啟用拖動(dòng)

為頁(yè)面視圖控件創(chuàng)建拖動(dòng)手勢(shì)識(shí)別器(DragGestureRecognizer), 它定義了以下屬性:

屬性 類型 描述
CanDrag bool 指明手勢(shì)識(shí)別器附加到的控件能否為拖動(dòng)源。 此屬性的默認(rèn)值為 true。
CanDrag bool 指明手勢(shì)識(shí)別器附加到的控件能否為拖動(dòng)源。 此屬性的默認(rèn)值為 true。
DragStartingCommand ICommand 在第一次識(shí)別拖動(dòng)手勢(shì)時(shí)執(zhí)行。
DragStartingCommandParameter object 是傳遞給 DragStartingCommand 的參數(shù)。
DropCompletedCommand ICommand 在放置拖動(dòng)源時(shí)執(zhí)行。
DropCompletedCommandParameter object 是傳遞給 DropCompletedCommand 的參數(shù)。

啟用放置

為頁(yè)面視圖控件創(chuàng)建放置手勢(shì)識(shí)別器(DropGestureRecognizer), 它定義了以下屬性:

屬性 類型 描述
AllowDrop bool 指明手勢(shì)識(shí)別器附加到的元素能否為放置目標(biāo)。 此屬性的默認(rèn)值為 true。
DragOverCommand ICommand 在拖動(dòng)源被拖動(dòng)到放置目標(biāo)上時(shí)執(zhí)行。
DragOverCommandParameter object 是傳遞給 DragOverCommand 的參數(shù)。
DragLeaveCommand ICommand 在拖動(dòng)源被拖至放置目標(biāo)上時(shí)執(zhí)行。
DragLeaveCommandParameter object 是傳遞給 DragLeaveCommand 的參數(shù)。
DropCommand ICommand 在拖動(dòng)源被放置到放置目標(biāo)上時(shí)執(zhí)行。
DropCommandParameter object 是傳遞給 DropCommand 的參數(shù)。

創(chuàng)建可拖拽控件的綁定類,實(shí)現(xiàn)IDraggableItem接口,定義拖動(dòng)相關(guān)的屬性和命令。

public interface IDraggableItem
{
    bool IsBeingDraggedOver { get; set; }
    bool IsBeingDragged { get; set; }
    Command Dragged { get; set; }
    Command DraggedOver { get; set; }
    Command DragLeave { get; set; }
    Command Dropped { get; set; }
    object DraggedItem { get; set; }
    object DropPlaceHolderItem { get; set; }
}

Dragged: 拖拽開(kāi)始時(shí)觸發(fā)的命令。
DraggedOver: 拖拽控件懸停在當(dāng)前控件上方時(shí)觸發(fā)的命令。
DragLeave: 拖拽控件離開(kāi)當(dāng)前控件時(shí)觸發(fā)的命令。
Dropped: 拖拽控件放置在當(dāng)前控件上方時(shí)觸發(fā)的命令。

IsBeingDragged 為true時(shí),通知當(dāng)前控件正在被拖拽。
IsBeingDraggedOver 為true時(shí),通知當(dāng)前控件正在有拖拽控件懸停在其上方。

DraggedItem: 正在拖拽的控件。
DropPlaceHolderItem: 懸停在其上方時(shí)的控件,即當(dāng)前控件的占位控件。

此時(shí)可拖拽控件為磁貼片段(TileSegement), 創(chuàng)建一個(gè)類用于描述磁貼可顯示的屬性,如標(biāo)題、描述、圖標(biāo)、顏色等。

public class TileSegment 
{
    public string Title { get; set; }
    public string Type { get; set; }
    public string Desc { get; set; }
    public string Icon { get; set; }
    public Color Color { get; set; }
}

創(chuàng)建綁定服務(wù)類

創(chuàng)建可拖拽控件的綁定服務(wù)類TileSegmentService,繼承ObservableObject,并實(shí)現(xiàn)IDraggableItem接口。

public class TileSegmentService : ObservableObject, ITileSegmentService
{
    ...
}

拖拽(Drag)

拖拽開(kāi)始時(shí),將IsBeingDragged設(shè)置為true,通知當(dāng)前控件正在被拖拽,同時(shí)將DraggedItem設(shè)置為當(dāng)前控件。

private void OnDragged(object item)
{
    IsBeingDragged=true;
    DraggedItem=item;
}

拖拽懸停,經(jīng)過(guò)(DragOver)

拖拽控件懸停在當(dāng)前控件上方時(shí),將IsBeingDraggedOver設(shè)置為true,通知當(dāng)前控件正在有拖拽控件懸停在其上方,同時(shí)在服務(wù)列表中尋找當(dāng)前正在被拖拽的服務(wù),將DropPlaceHolderItem設(shè)置為當(dāng)前控件。

private void OnDraggedOver(object item)
{
    if (!IsBeingDragged && item!=null)
    {
        IsBeingDraggedOver=true;

        var itemToMove = Container.TileSegments.First(i => i.IsBeingDragged);
        if (itemToMove.DraggedItem!=null)
        {
            DropPlaceHolderItem=itemToMove.DraggedItem;

        }
    }

}

離開(kāi)控件上方時(shí),IsBeingDraggedOver設(shè)置為false

private void OnDragLeave(object item)
{
    IsBeingDraggedOver = false;
}

釋放(Drop)

拖拽完成時(shí),獲取當(dāng)前正在被拖拽的控件,將其從服務(wù)列表中移除,然后將其插入到當(dāng)前控件的位置,通知當(dāng)前控件拖拽完成。

private void OnDropped(object item)
{
    var itemToMove = Container.TileSegments.First(i => i.IsBeingDragged);

    if (itemToMove == null ||  itemToMove == this)
        return;


    Container.TileSegments.Remove(itemToMove);

    var insertAtIndex = Container.TileSegments.IndexOf(this);

    Container.TileSegments.Insert(insertAtIndex, itemToMove);
    itemToMove.IsBeingDragged = false;
    IsBeingDraggedOver = false;
    DraggedItem=null;

}

完整的TileSegmentService代碼如下:

public class TileSegmentService : ObservableObject, ITileSegmentService
{

    public TileSegmentService(
        TileSegment tileSegment)
    {
        Remove = new Command(RemoveAction);
        TileSegment = tileSegment;

        Dragged = new Command(OnDragged);
        DraggedOver = new Command(OnDraggedOver);
        DragLeave = new Command(OnDragLeave);
        Dropped = new Command(i => OnDropped(i));

    }

    private void OnDragged(object item)
    {
        IsBeingDragged=true;
    }

    private void OnDraggedOver(object item)
    {
        if (!IsBeingDragged && item!=null)
        {
            IsBeingDraggedOver=true;

            var itemToMove = Container.TileSegments.First(i => i.IsBeingDragged);
            if (itemToMove.DraggedItem!=null)
            {
                DropPlaceHolderItem=itemToMove.DraggedItem;

            }
        }

    }


    private object _draggedItem;

    public object DraggedItem
    {
        get { return _draggedItem; }
        set
        {
            _draggedItem = value;
            OnPropertyChanged();
        }
    }

    private object _dropPlaceHolderItem;

    public object DropPlaceHolderItem
    {
        get { return _dropPlaceHolderItem; }
        set
        {
            _dropPlaceHolderItem = value;
            OnPropertyChanged();
        }
    }

    private void OnDragLeave(object item)
    {

        IsBeingDraggedOver = false;
        DraggedItem = null;

    }

    private void OnDropped(object item)
    {
        var itemToMove = Container.TileSegments.First(i => i.IsBeingDragged);

        if (itemToMove == null ||  itemToMove == this)
            return;


        Container.TileSegments.Remove(itemToMove);

        var insertAtIndex = Container.TileSegments.IndexOf(this);

        Container.TileSegments.Insert(insertAtIndex, itemToMove);
        itemToMove.IsBeingDragged = false;
        IsBeingDraggedOver = false;
        DraggedItem=null;

    }

    private async void RemoveAction(object obj)
    {
        if (Container is ITileSegmentServiceContainer)
        {
            (Container as ITileSegmentServiceContainer).RemoveSegment.Execute(this);
        }
    }


    public IReadOnlyTileSegmentServiceContainer Container { get; set; }


    private TileSegment tileSegment;

    public TileSegment TileSegment
    {
        get { return tileSegment; }
        set
        {
            tileSegment = value;
            OnPropertyChanged();

        }
    }


    private bool _isBeingDragged;
    public bool IsBeingDragged
    {
        get { return _isBeingDragged; }
        set
        {
            _isBeingDragged = value;
            OnPropertyChanged();

        }
    }

    private bool _isBeingDraggedOver;
    public bool IsBeingDraggedOver
    {
        get { return _isBeingDraggedOver; }
        set
        {
            _isBeingDraggedOver = value;
            OnPropertyChanged();

        }
    }

    public Command Remove { get; set; }


    public Command Dragged { get; set; }

    public Command DraggedOver { get; set; }

    public Command DragLeave { get; set; }

    public Command Dropped { get; set; }
}

創(chuàng)建頁(yè)面元素

在Controls目錄下創(chuàng)建不同大小的磁貼控件,如下圖所示。

[MAUI]在.NET MAUI中實(shí)現(xiàn)可拖拽排序列表,.NET MAUI,產(chǎn)品設(shè)計(jì),.net,xamarin

在MainPage中創(chuàng)建CollectionView,用于將磁貼元素以列表形式展示。

<CollectionView Grid.Row="1"
                x:Name="MainCollectionView"
                ItemsSource="{Binding TileSegments}"
                ItemTemplate="{StaticResource TileSegmentDataTemplateSelector}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical" />
    </CollectionView.ItemsLayout>
</CollectionView>

創(chuàng)建MainPageViewModel,創(chuàng)建綁定服務(wù)類集合TileSegments,初始化中添加一些不同顏色,大小的磁貼,并將TileSegementService.Container設(shè)置為自己(this)。

不同大小的磁貼通過(guò)綁定相應(yīng)的數(shù)據(jù),使用不同的數(shù)據(jù)模板進(jìn)行展示。請(qǐng)閱讀博文 [MAUI程序設(shè)計(jì)]界面多態(tài)與實(shí)現(xiàn),了解如何實(shí)現(xiàn)列表Item的多態(tài)。

[MAUI]在.NET MAUI中實(shí)現(xiàn)可拖拽排序列表,.NET MAUI,產(chǎn)品設(shè)計(jì),.net,xamarin

在MainPage中創(chuàng)建磁貼片段數(shù)據(jù)模板選擇器(TileSegmentDataTemplateSelector),用于根據(jù)磁貼片段的大小選擇不同的數(shù)據(jù)模板。

<DataTemplate x:Key="SmallSegment">
    <controls1:SmallSegmentView  Margin="0,5"
                                    ControlTemplate="{StaticResource TileSegmentTemplate}">
    </controls1:SmallSegmentView>
</DataTemplate>
<DataTemplate x:Key="MediumSegment">
    <controls1:MediumSegmentView Margin="0,5"
                                    ControlTemplate="{StaticResource TileSegmentTemplate}">

    </controls1:MediumSegmentView>
</DataTemplate>
<DataTemplate x:Key="LargeSegment">
    <controls1:LargeSegmentView Margin="0,5"
                                ControlTemplate="{StaticResource TileSegmentTemplate}">

    </controls1:LargeSegmentView>
</DataTemplate>
<controls1:TileSegmentDataTemplateSelector x:Key="TileSegmentDataTemplateSelector"
                                            ResourcesContainer="{x:Reference Main}" />

創(chuàng)建磁貼控件模板TileSegmentTemplate,并在此指定DropGestureRecognizer

<ControlTemplate x:Key="TileSegmentTemplate">
    <ContentView>
        <StackLayout>
            <StackLayout.GestureRecognizers>
                <DropGestureRecognizer AllowDrop="True"
                                        DragLeaveCommand="{TemplateBinding BindingContext.DragLeave}"
                                        DragLeaveCommandParameter="{TemplateBinding}"
                                        DragOverCommand="{TemplateBinding BindingContext.DraggedOver}"
                                        DragOverCommandParameter="{TemplateBinding}"
                                        DropCommand="{TemplateBinding BindingContext.Dropped}"
                                        DropCommandParameter="{TemplateBinding}" />
            </StackLayout.GestureRecognizers>
            
        </StackLayout>
    </ContentView>
</ControlTemplate>

創(chuàng)建磁貼控件外觀Layout,<ContentPresenter />處將呈現(xiàn)磁貼片段的內(nèi)容。在Layout指定DragGestureRecognizer。

<Border x:Name="ContentLayout"
        Margin="0">
    <Grid>
        <Grid.GestureRecognizers>
            <DragGestureRecognizer CanDrag="True"
                                    DragStartingCommand="{TemplateBinding BindingContext.Dragged}"
                                    DragStartingCommandParameter="{TemplateBinding}" />
        </Grid.GestureRecognizers>

        <ContentPresenter />
        <Button CornerRadius="100"
                HeightRequest="20"
                WidthRequest="20"
                Padding="0"
                BackgroundColor="Red"
                TextColor="White"
                Command="{TemplateBinding BindingContext.Remove}"
                Text="×"
                HorizontalOptions="End"
                VerticalOptions="Start"></Button>
    </Grid>
</Border>

[MAUI]在.NET MAUI中實(shí)現(xiàn)可拖拽排序列表,.NET MAUI,產(chǎn)品設(shè)計(jì),.net,xamarin

創(chuàng)建占位控件,用于指示松開(kāi)手指時(shí),控件將放置的位置區(qū)域,在這里綁定DropPlaceHolderItem的高度和寬度。

<Border StrokeThickness="4"
        StrokeDashArray="2 2"
        StrokeDashOffset="6"
        Stroke="black"
        HorizontalOptions="Center"
        IsVisible="{TemplateBinding BindingContext.IsBeingDraggedOver}">
    <Grid HeightRequest="{TemplateBinding BindingContext.DropPlaceHolderItem.Height}"
            WidthRequest="{TemplateBinding BindingContext.DropPlaceHolderItem.Width}">
        <Label HorizontalTextAlignment="Center"
                VerticalOptions="Center"
                Text="松開(kāi)手指將放置條目至此處"></Label>


    </Grid>
</Border>

最終效果

[MAUI]在.NET MAUI中實(shí)現(xiàn)可拖拽排序列表,.NET MAUI,產(chǎn)品設(shè)計(jì),.net,xamarin

項(xiàng)目地址

Github:maui-samples

關(guān)注我,學(xué)習(xí)更多.NET MAUI開(kāi)發(fā)知識(shí)!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-652027.html

到了這里,關(guān)于[MAUI]在.NET MAUI中實(shí)現(xiàn)可拖拽排序列表的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 實(shí)現(xiàn)ElementUI tab標(biāo)簽可拖拽

    通過(guò)sortablejs實(shí)現(xiàn) 參考:https://blog.csdn.net/wangjiecsdn/article/details/121995534

    2024年01月22日
    瀏覽(20)
  • 前端彈窗可拖拽功能實(shí)現(xiàn)

    ? ? ? ?前端彈窗可拖拽功能主要實(shí)現(xiàn)思路就是監(jiān)聽(tīng)鼠標(biāo)移動(dòng)事件,根據(jù)鼠標(biāo)位置實(shí)時(shí)修改彈窗距離父級(jí)窗口(或者屏幕,根據(jù)需求設(shè)置)的left和right,但是考慮到鼠標(biāo)拖拽一般都是在div的標(biāo)題欄處發(fā)生,鼠標(biāo)按下的位置不可能是彈窗的左上角位置,為此需要計(jì)算 鼠標(biāo)按下的

    2024年02月19日
    瀏覽(29)
  • vue 進(jìn)度條組件(可拖拽可點(diǎn)擊)

    vue 進(jìn)度條組件(可拖拽可點(diǎn)擊)

    在日常的開(kāi)發(fā)當(dāng)中,隨著項(xiàng)目的需求復(fù)雜化,自定義組件也越來(lái)越常見(jiàn),而且擴(kuò)展性也比一些組件庫(kù)要更加全面,比如視頻播放器的進(jìn)度條。 可自定義設(shè)置以下屬性: 當(dāng)前進(jìn)度value,默認(rèn)50 是否可拖拽isDrag,默認(rèn)true 設(shè)置最小值min,默認(rèn)0 設(shè)置最大值max,默認(rèn)100 進(jìn)度條顏色

    2024年02月16日
    瀏覽(28)
  • 可拖拽編輯的流程圖X6

    可拖拽編輯的流程圖X6

    ?先上圖

    2024年02月11日
    瀏覽(18)
  • Vue3封裝可拖拽的彈窗

    核心代碼(復(fù)制就可以使用了) 使用方式

    2024年01月19日
    瀏覽(25)
  • vue3實(shí)現(xiàn)組件可拖拽 vuedraggable

    npm i -S vuedraggable@next 中文文檔,里面有完整代碼案例,值得一看 vue.draggable vue3 版本在工作臺(tái)中的應(yīng)用場(chǎng)景 - itxst.com

    2024年02月13日
    瀏覽(32)
  • Qt編寫可拖拽的自定義控件

    Qt編寫可拖拽的自定義控件

    一直想做一個(gè)像卡牌游戲一樣的,可以拖動(dòng)卡片,實(shí)現(xiàn)改變位置,順序交換的效果,今天我們一起來(lái)嘗試一下。 類名為Card h文件 cpp文件 我們完成了一個(gè)很簡(jiǎn)單的200*400的圓角卡片 在主界面中展示看看 widget.h widget.cpp 運(yùn)行后的效果: 首先要實(shí)現(xiàn)控件拖動(dòng),需要有2個(gè)要素,1:

    2024年02月11日
    瀏覽(26)
  • 【微信小程序-原生開(kāi)發(fā)】列表 - 拖拽排序(官方組件 movable-area 和 movable-view 的用法)

    【微信小程序-原生開(kāi)發(fā)】列表 - 拖拽排序(官方組件 movable-area 和 movable-view 的用法)

    實(shí)現(xiàn)邏輯詳見(jiàn)代碼的注釋 需要根據(jù)各項(xiàng)的內(nèi)容,調(diào)整或動(dòng)態(tài)生成 ITEM_HEIGHT 值 因 movable-view 是絕對(duì)定位,不方便實(shí)現(xiàn)水平居中,所以設(shè)定 width: 100%; 占滿寬度

    2024年02月11日
    瀏覽(23)
  • 基于vue的可拖拽設(shè)計(jì)的報(bào)表看板設(shè)計(jì)器

    基于vue的可拖拽設(shè)計(jì)的報(bào)表看板設(shè)計(jì)器

    gitee上的不錯(cuò)項(xiàng)目,基于vue實(shí)現(xiàn)的可拖拽的看板設(shè)計(jì)器可以自由搭配顏色和圖標(biāo),開(kāi)發(fā)者可以只關(guān)注業(yè)務(wù)數(shù)據(jù)接口,前端不擅長(zhǎng)的人員可以直接輕松上手。 1.可支持的元素 文字,邊框,常見(jiàn)圖表,柱形圖,折線餅圖等等,還有一些列表數(shù)據(jù),當(dāng)然還支持iframe嵌套,當(dāng)組件滿足

    2024年02月11日
    瀏覽(34)
  • 基于vue+Element UI的文件上傳(可拖拽上傳)

    基于vue+Element UI的文件上傳(可拖拽上傳)

    drag: 支持拖拽上傳 action:必選參數(shù),上傳的地址 ref:這里主要是用于文件上傳完成后清除文件的 on-remove:文件列表移除文件時(shí)的鉤子 auto-upload:是否在選取文件后立即進(jìn)行上傳 on-change:文件狀態(tài)改變時(shí)的鉤子,添加文件、上傳成功和上傳失敗時(shí)都會(huì)被調(diào)用 注:這里使用的

    2023年04月08日
    瀏覽(30)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包