MAUI Xaml 버튼 컨드롤을 안쓰고 , 버튼 만들수가 있나요?

이번에 처음으로 XAML 마우이 버전을 만들어 봅니다.

WPF 와 다르게 쓰는 이름들이 조금씩 틀린것도 있네요 .

TextBlock → Label

FontWeight → FontAttributes

Foreground → TextColor

HorizontalAlignment → HorizontalOptions

VerticalAlignment → VerticalOptions

VerticalAlignment = “Top” → VerticalOptions=“Start”
HorizontalAlignment =“Right” → HorizontalOptions= “End”

마우이에서 Border 의 line 을 "1 1 0 0 " 형식으로 설정할수 없음.
라인으로 그릴경우 , 다른 컨트롤 사용

Button 의 Content → Text

Button 에서는 Template 안됨. (textAlignment 설정불가능)

CheckBox 에서는 Template 안됨.

WPF 에서 xaml 을 만들어서 , 마우이에서 바로 사용하려했으나… 안되네요 ㅜㅜ

그래서 컨트롤 배제하고?? Flutter 처럼 컨트롤 안쓰고 , InkWell 이나 GestureDetector 같은 형식으로 사용 할수 있을까요???

1 Like

WPF와 MAUI의 XAML 개념은 좀 다릅니다.

  • Maui에서 Border line은 바로 쓸수있고 Stroke, StokreLine, StrokeShape를 통해야만
    WPF의 Border처럼 사용할 수 있습니다.

  • WPF에서의 Content는 텍스트 뿐만 아니라 컨트롤들도 들어가기 때문에 Text 외 다른것들도 들어갈 수 있습니다.

  • WPF에서는 ContentControl를 기반으로 여러 컨트롤들을 만들어내기 때문에 말씀하신 Template속성이 존재합니다. 하지만 Maui에서는 ContentControl같은 속성을 가지고 만들어내지 않습니다. 그렇다고해서 비슷하게 못만드는건 아닙니다. TemplateView를 상속받은 컨트롤에 한해서는 Template와 비슷하게 흉내낼 순 있습니다.

그래도 질문하신 버튼 컨트롤 쓰지 않고 버튼을 만들 수 있나요? 라는 질문에는
불가능하지않습니다…제가 조금 있다 시간되는대로 샘플올려드릴게요~

Screenshot 2024-08-16 at 13.07.50

다음 조건을 가지고 만들었습니다.

  • Template 기반의 내부에 자유롭게 구성할 수 있는가?
  • 컨트롤의 특성을 가지지 않고 GestureDetector를 통해서만 구성이 가능한가?
  <ContentView HeightRequest="50" WidthRequest="100">
      <ContentView.GestureRecognizers>
          <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
      </ContentView.GestureRecognizers>
      <ContentView.Style>
          <Style TargetType="{x:Type ContentView}">
              <Setter Property="ControlTemplate">
                  <ControlTemplate>
                      <Border
                          Padding="5"
                          Background="Thistle"
                          Stroke="Black">
                          <Border.StrokeShape>
                              <RoundRectangle CornerRadius="5" />
                          </Border.StrokeShape>
                          <Label
                              HorizontalTextAlignment="Center"
                              Text="hiuhi"
                              VerticalTextAlignment="Center" />
                      </Border>
                  </ControlTemplate>
              </Setter>
          </Style>
      </ContentView.Style>
  </ContentView>
2 Likes

오옷 감사합니다~ ^^
덕분에 대안책 찾았어요~ ^^
Border 에 제스쳐 걸면 더블클릭만되는데 , 컨텐츠뷰에서 잘 동작해요~ ^^

<Style x:Key="stl_btnTest"  TargetType="{x:Type ContentView}">
     <Setter Property="ControlTemplate">
         <ControlTemplate>
             <Border Padding="5" Background="Thistle" Stroke="Black">
                 <Border.StrokeShape>
                     <RoundRectangle CornerRadius="5" />
                 </Border.StrokeShape>
                 <ContentPresenter  Content="{TemplateBinding Content}"   />
             </Border>
         </ControlTemplate>
     </Setter>
 </Style>


<ContentView Style="{DynamicResource stl_btnTest}" HeightRequest="54" WidthRequest="300">
    <ContentView.GestureRecognizers>
        <TapGestureRecognizer Tapped="OnTapGestureRecognizerTapped" />
    </ContentView.GestureRecognizers>
    <ContentView.Content>
        <Grid Background="Red">
            <Label Text="테스트" VerticalOptions="Center" TextColor="White" />
            <Image Source="popupiconmenu4.png" WidthRequest="24" HeightRequest="24" HorizontalOptions="End" />
        </Grid>
    </ContentView.Content>
</ContentView>
2 Likes

마우이 버튼 만들어서 사용하려니 쉽지가 않네요 ㅜㅜ
ContentView 스타일에 VisualTree 넣어두고 , 상황에따라 호출하려하는데요…
어떻게 해야 사용할수 있나요ㅜㅜ

<ContentView      Style="{DynamicResource stl_btnCommon}"            >
    <ContentView.GestureRecognizers>
        <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" NumberOfTapsRequired="1" />
    </ContentView.GestureRecognizers>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        
        <Label Margin="24,24,0,0" x:Name="lbl_sale"
               Text="판매"
               Style="{DynamicResource stl_tbk32gray08Bold}"
               TextColor="{DynamicResource color_text_FFF}" />
        <Image Grid.Row="1"
               HorizontalOptions="End"
               VerticalOptions="End"
               Margin="0,0,0,32"
               WidthRequest="158"
               HeightRequest="158"
               Aspect="Fill"
               Source="ani1.png" />
    </Grid>
</ContentView>

 <Style x:Key="stl_btnCommon" TargetType="{x:Type ContentView}">
     <Setter Property="Background" Value="Transparent" />
     <Setter Property="BackgroundColor" Value="{DynamicResource color_control_FFF}" />
     <Setter Property="ControlTemplate">
         <ControlTemplate>
             <Grid Background="Transparent" BackgroundColor="Transparent">
                 <VisualStateManager.VisualStateGroups>
                     <VisualStateGroup x:Name="CommonStates">
                         <VisualState x:Name="Normal">
                             <VisualState.Setters>
                                 <Setter Property="Border.IsVisible"
                                         TargetName="border_sel"
                                         Value="Collapse" />
                             </VisualState.Setters>
                         </VisualState>
                         <VisualState x:Name="Selected">
                             <VisualState.Setters>
                                 <Setter Property="Border.IsVisible"
                                         TargetName="border_sel"
                                         Value="Visible" />
                             </VisualState.Setters>
                         </VisualState>
                     </VisualStateGroup>
                 </VisualStateManager.VisualStateGroups>
                
                 <Border x:Name="border_sel"
                         IsVisible="Visible"
                         Background="#ff6600">
                     <Border.StrokeShape>
                         <RoundRectangle CornerRadius="8" />
                     </Border.StrokeShape>
                 </Border>
             </Grid>
         </ControlTemplate>
     </Setter>
 </Style>

private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
    lbl_sale.Text = "판매 완료";
    
    count++;

    if (isPressed)
    {
        **VisualStateManager.GoToState(this, VisualStateManager.CommonStates.Normal);**
        isPressed = false;
       
    }
    else
    {
        **VisualStateManager.GoToState(this, VisualStateManager.CommonStates.Selected);**
        isPressed = true;
        lbl_sale.Text = "판매";
    }
}
1 Like

개인적인 일 때문에
낼 샘플코드를 …작성해드릴게요

이부분에 누락되었어요 ㅠ…

<ContentPresenter  Content="{TemplateBinding Content}"   />
<!--현재-->
<Border x:Name="border_sel"
                IsVisible="Visible"
                Background="#ff6600">
       <Border.StrokeShape>
              <RoundRectangle CornerRadius="8" />
       </Border.StrokeShape>
</Border>

<!--변경-->
<Border x:Name="border_sel"
                IsVisible="Visible"
                Background="#ff6600">
       <Border.StrokeShape>
              <RoundRectangle CornerRadius="8" />
       </Border.StrokeShape>
       <ContentPresenter  Content="{TemplateBinding Content}"   />
</Border>

앗… 올린 소스에서 너무길어서 ContentPresenter 부분은 누락하고 올렸어요.
다른건 문제없이 동작하는데 , 화면 터치할때 , Statet 변화가 없어서요~ ㅜㅜ
VisualStateManager.GoToState(this, VisualStateManager.CommonStates.Normal);

아아…이제야 이해는 됬네요…
근데 VisualStateManager.VisualStateGroups은 결국 ContentView의 VisualStateManager가 아닌 Grid의 VisualStateManager 이 된게 아닌가요?