Equalisys
Equalisys

Reputation: 25

How to make a Label Selectable in .NET 7 MAUI with XAML?

I am creating a password generator and I don't know how to make the label (where the program puts the generated password) selectable but not editable... How to do it ?

Here is my mainpage.xaml code :

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="PassGen.MainPage">
    

    <ScrollView
        BackgroundColor="DarkSlateGray">
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">

            <Label
                x:Name="PasswordLabel"
                HorizontalOptions="Center"
                Text="Click Generate to generate a password"
                FontAttributes="Italic"
                
           
            ></Label>


            <Button
                BackgroundColor="Coral"
                Text="Generate"
                Clicked="GeneratePassword"
            ></Button>
            

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

Upvotes: 1

Views: 2389

Answers (2)

user23372732
user23372732

Reputation: 31

Making Label Selectable Using Handlers in .Net Maui

Hi @Equalisys,

I don't know if an answer to your question is still relevant (given it has being 9 months since you asked) but I thought I would post my implementation incase anyone else may come across the same problem.

I managed to make the label selectable by using Handlers in .Net Maui. The steps are outlined as follows (with code snippets):

  1. Create a class that inherits from the control you want to customize. In this case, it would be a label. In my case: namespace Your_Namespace { internal class MyLabel: Label { } }

  2. Within the constructor of your App.xaml.cs file, add the following code:

Microsoft.Maui.Handlers.LabelHandler.Mapper.AppendToMapping("MyLblCustomization", (handler, view) => { if(view is MyLabel) { #if ANDROID handler.PlatformView.SetTextIsSelectable(true); #elif WINDOWS handler.PlatformView.IsTextSelectionEnabled = true; #endif } });

Note: I used conditional compilation to write code for both windows and android platforms. In some articles, it is stated that you can place the code within the platform specific folders.

  1. Go to the front end of the page you want to add the control - in my case it was MainPage.xaml. Here, add in the namespace (of where your subclass lives), import the class and use the custom label. Set the properties accordingly. When you run the application, the label should now be selectable.

Add namespace. In my case, the class (MyLabel) lives inside a folder called ControlsCustomize:

<ContentPage 
         xmlns:CustomControls ="clr-namespace:Test_LblSelect_Theme_NavBar.ControlsCustomize">

Import class and use custom label:

<CustomControls:MyLabel
            Text="Hello, World! Welcome to .NET Multi-platform App UI | Hello, World! Welcome to .NET Multi-platform App UI | Hello, World! Welcome to .NET Multi-platform App UI"
            x:Name="mylabel"
            >
</CustomControls:MyLabel>

After doing this, the label should be selectable. I tried it on both android and windows platforms, and it worked as expected. The label is selectable as shown.

Note:

  • I tested it on Windows 10 and Android API 33 (Simulator)
  • This is a helpful article on Handlers
  • This another helpful article on handlers. This particular article very straightforward and easy to follow.

Hope it helps.

Upvotes: 3

Jessie Zhang -MSFT
Jessie Zhang -MSFT

Reputation: 13889

Yes, you can try to add a tap gesture to your Label and get the text of the Label or add a button to get the text of the Label.

I have used two ways to achieve this function. You can refer to the following code:

public class MyViewModel: INotifyPropertyChanged 
{
    public ICommand TapCommand { get; set; }

    public ICommand GetPwdCommand { get; set; }


    private string _password ="123456";
    public string Password
    {
        get => _password;
        set
        {
            SetProperty(ref _password, value);
        }
    }

    public MyViewModel()
    {

        TapCommand = new Command<object>(OnLabelTapped);

        GetPwdCommand = new Command(getPwdFromEntry);

    }

    private void getPwdFromEntry()
    {
        System.Diagnostics.Debug.WriteLine("method 1-----> Password = " + Password);

    }

    private void OnLabelTapped(object obj)
    {
        if (obj is Label )
        {
            var label = (Label)obj;

            string str = label.Text;

            System.Diagnostics.Debug.WriteLine("method 2--- >Password = " + str);
        }
    }
}

Usage example:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiMvvmApp226.CollectionViewPage"
             xmlns:MauiMvvmApp="clr-namespace:MauiMvvmApp"
             Title="CollectionViewPage">

    <ContentPage.BindingContext>
        <MauiMvvmApp:MyViewModel></MauiMvvmApp:MyViewModel>
    </ContentPage.BindingContext>

    <VerticalStackLayout>
        <Label
                x:Name="PasswordLabel"
                HorizontalOptions="Center"
                Text="Click Generate to generate a password" HeightRequest="50"
                >
            <Label.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding TapCommand}" CommandParameter="{Binding Source={x:Reference PasswordLabel}}">
                </TapGestureRecognizer>
            </Label.GestureRecognizers>
        </Label>


        <Entry  x:Name="mEntry" IsReadOnly="True"  Text="{Binding Password}" />
        <Button
                Command="{Binding GetPwdCommand}"
                BackgroundColor="Coral"
                Text="Generate">
        </Button>


    </VerticalStackLayout>
</ContentPage>

Upvotes: 3

Related Questions