WPF 개발 기법 의 꽃 컨트롤 기능 확장 상세 설명

12608 단어 wpf컨트롤
글 은 당신 이 이미 WPF 에 들 어 갔다 는 것 을 묵인 합 니 다.
WPF 의 일상적인 개발 로 기본 컨트롤 기능 이 수 요 를 만족 시 키 지 못 하 는 경우 가 많 습 니 다.어떻게 해 야 합 니까?
No1.사용자 정의 컨트롤 템 플 릿
평소 개발 에 서 는'속 된'수 요 를 비교 하고 컨트롤 의 기본 적 인 모습 을 싫어한다.어 떡 하지?하하,그럼 전체 얼굴 이지......................................................😜!
마음 깊 은 곳 에 있 는 버튼 기억 나 세 요?첫 인상 이 바로 반듯 한 직사각형 이 었 나 요?자,이번 에는 속 도 를 내 서 원형 으로 만 듭 시다!
상위 코드:

<Button Content="Test1" Width="80" Height="80" FocusVisualStyle="{x:Null}" Background="LightSeaGreen" BorderBrush="DarkBlue">
                <Button.Template>
                    <ControlTemplate TargetType="ButtonBase">
                        <Grid>
                            <Ellipse x:Name="ellipseBorder" StrokeThickness="1" Stroke="{TemplateBinding BorderBrush}" Fill="{TemplateBinding Background}"/>
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding Content}"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Stroke" Value="Orange" TargetName="ellipseBorder"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Stroke" Value="OrangeRed" TargetName="ellipseBorder"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Button.Template>
            </Button>
겉보기:

No 2.다시 쓰기 컨트롤
많은 경우 에 컨트롤 을 외모 로 바 꾸 면 해결 되 는 것 이 아 닙 니 다.우 리 는 외 모 를 바 꿔 야 할 뿐만 아니 라 컨트롤 의 기능 도 바 꿔 야 합 니 다.예 를 들 어 우리 가 자주 사용 하 는 TextBox 컨트롤,정상 적 인 기능 은 입력 하 는 것 이지 만 더욱 인성 화 된 점 입 니 다.TextBox 는 현재 텍스트 상자 에 사용자 이름 을 입력 해 야 하 는 지,주 소 를 입력 해 야 하 는 지 등 을 알려 주 고 싶 습 니 다.사실은 이것 이 바로 우리 가 자주 보 는 워 터 마크 기능 이다.워 터 마크 문 자 는 반드시 필요 에 따라 설정 할 수 있어 야 한다.그러면 우 리 는 간단하게 컨트롤 템 플 릿 을 바 꾸 면 해결 할 수 없다.
수 요 를 통 해 우 리 는 새로운 워 터 마크 가 있 는 텍스트 상자 에 적어도 워 터 마크 와 같은 의존 속성 이 있어 외부 설정 을 할 수 있다 는 것 을 알 게 되 었 다.물론 새로운 워 터 마크 텍스트 상자 와 TextBox 의 모양 은 크게 다 르 지 않 지만 새로운 컨트롤 에 외 모 를 정의 해 야 합 니 다.
그래서 첫 번 째 단 계 는 컨트롤 의 기능 을 정의 하고 코드 를 올 립 니 다.

public class WaterMarkTextBox : TextBox
    {
        static WaterMarkTextBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(WaterMarkTextBox), new FrameworkPropertyMetadata(typeof(WaterMarkTextBox)));
        }


        public string WaterMark
        {
            get { return (string)GetValue(WaterMarkProperty); }
            set { SetValue(WaterMarkProperty, value); }
        }

        // Using a DependencyProperty as the backing store for WaterMark.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty WaterMarkProperty =
            DependencyProperty.Register("WaterMark", typeof(string), typeof(WaterMarkTextBox), new PropertyMetadata(null));


    }

두 번 째 단 계 는 컨트롤 의 모양 을 정의 하고 코드 를 올 립 니 다.

<Style TargetType="{x:Type local:WaterMarkTextBox}">
        <Setter Property="BorderBrush" Value="Black"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:WaterMarkTextBox}">
                    <Grid>
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                        </Border>
                        <ScrollViewer x:Name="PART_ContentHost"
                                      Grid.Column="0"
                                      Margin="0"
                                      Padding="{TemplateBinding Padding}"
                                      VerticalAlignment="Stretch"
                                      Background="{x:Null}"
                                      BorderThickness="0"
                                      IsTabStop="False"
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        <TextBlock x:Name="PART_Message"
                                   Margin="4 0"
                                   Padding="{TemplateBinding Padding}"
                                   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                   VerticalAlignment="Center"
                                   Foreground="Gray"
                                   Text="{TemplateBinding WaterMark}"
                                   Visibility="Collapsed" />
                    </Grid>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
                            <Setter TargetName="PART_Message" Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </ControlTemplate.Triggers>
                    
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
Name 은 PARTMessage 의 TextBlock 은 워 터 마크 알림 메 시 지 를 보 여 주 는 동시에 트리거 를 추가 하여 이러한 기능 을 실현 합 니 다.내용 을 입력 하지 않 으 면 워 터 마크 를 표시 하고 그렇지 않 으 면 워 터 마크 를 숨 깁 니 다.
컨트롤 사용,코드:

 <local:WaterMarkTextBox Margin="20,0,0,0" Width="200" Height="50" WaterMark="Please Input your name"/>
위의 효과:

No 3.속성 추가 해 보기
재 작성 컨트롤 이 완벽 해 보 입 니 다.정말 그렇습니까?
자,제 요구 가 또 왔 습 니 다.지금 텍스트 상자 의 힌트 는 매우 perfect 입 니 다.하지만 제 암호 상자 Password Box 도 워 터 마크 를 만들어 야 합 니까?어 떡 하지?워 터 마크 가 있 는 암호 상 자 를 다시 쓸 까요?이때 같은 일 을 한 느낌 이 들 지 않 나 요?합 격 된 부농 으로서 우 리 는 부농 계 의 경 세 명언 인 Don't Repeat Yourself 를 명심 해 야 한다.
이때 WPF 의 고전 지식 포 인 트 를 기억 하 세 요:
컨트롤 A 는 Grid 에 넣 고 A 는 설정 줄 과 열 을 지원 하 며 컨트롤 B 는 Grid 에 넣 고 B 도 설정 줄 과 열 을 지원 해 야 합 니 다.튜 토리 얼 에서 바보 같이 A 와 B 에서 줄 과 열의 속성 을 정의 하지 말 라 고 했 습 니 다.그렇지 않 으 면 후속 C,D.......................................................
이때 가 바로 우리 가 추가 속성 을 적용 할 때 입 니 다.Grid 에서 통 일 된 줄 과 열의 추가 속성 을 정의 한 다음 에 A,B 에 추가 하면 됩 니 다.
반대로 우리 의 현재 수 요 를 살 펴 보 자.똑 같은 방법 이 아 닐 까?나 는 공공 장소 에서 워 터 마크 의 추가 속성 을 정의 한 다음 에 각각 텍스트 상자 와 암호 상자 에 적용 하면 되 는 것 입 니까?절반 은 맞 았 습 니 다.텍스트 상자 와 암호 상자 의 오래된 외모 에 워 터 마크 가 표시 되 지 않 았 기 때문에 우 리 는 동시에 그들의 새로운 외 모 를 다시 정의 해 야 합 니 다.
말 이 많 지 않 습 니 다.먼저 속성 정 의 를 추가 한 코드 를 올 립 니 다.

public class WaterMarkHelper
    {
        public static string GetWaterMark(DependencyObject obj)
        {
            return (string)obj.GetValue(WaterMarkProperty);
        }

        public static void SetWaterMark(DependencyObject obj, string value)
        {
            obj.SetValue(WaterMarkProperty, value);
        }

        public static readonly DependencyProperty WaterMarkProperty =
            DependencyProperty.RegisterAttached("WaterMark", typeof(string), typeof(WaterMarkHelper), new PropertyMetadata(null));


    }

텍스트 박스 의 새로운 스타일:

<Style x:Key="TextBoxWithWaterMark" TargetType="{x:Type TextBox}">
        <Setter Property="BorderBrush" Value="Black"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Grid>
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}">
                        </Border>
                        <ScrollViewer x:Name="PART_ContentHost"
                                      Grid.Column="0"
                                      Margin="0"
                                      Padding="{TemplateBinding Padding}"
                                      VerticalAlignment="Stretch"
                                      Background="{x:Null}"
                                      BorderThickness="0"
                                      IsTabStop="False"
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        <TextBlock x:Name="PART_Message"
                                   Margin="4 0"
                                   Padding="{TemplateBinding Padding}"
                                   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                   VerticalAlignment="Center"
                                   Foreground="Gray"
                                   Text="{TemplateBinding local:WaterMarkHelper.WaterMark}"
                                   Visibility="Collapsed" />
                    </Grid>
                    <ControlTemplate.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
                            <Setter TargetName="PART_Message" Property="Visibility" Value="Visible" />
                        </DataTrigger>
                    </ControlTemplate.Triggers>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

사용자 정의 컨트롤 의 스타일 과 비교 해 보 세 요.사실은 PART 입 니 다.Message 에 대응 하 는 컨트롤 의 Text 바 인 딩 이 다 릅 니 다.이 바 인 딩 은 TextBox 의 추가 속성 인 WaterMark Helper.WaterMark 입 니 다.
응용 코드:

 <TextBox Style="{StaticResource TextBoxWithWaterMark}" Margin="20,0,0,0" Width="200" Height="50" local:WaterMarkHelper.WaterMark="Please Input your name"/>
정 의 된 스타일 자원 을 수 동 으로 명확 하 게 적용 해 야 합 니 다!
위의 효과:
 
방과 후 숙제:그대로 PasswordBox 의 워 터 마크 기능 을 실현 하 세 요.😆
총결산
여기 열거 한 세 가지 방식 을 제외 하고 Behavior 행위 기능 을 통 해 유명한 드래그 기능 과 같은 컨트롤 기능 을 확장 할 수 있 습 니 다!여기까지 쓰 고 내 가 정리 하고 싶 은 것 은 일 을 잘 하려 면 반드시 그 기 구 를 먼저 이 롭 게 해 야 한 다 는 것 이다!
우리 가 기초 가 탄탄 한 후에 우 리 는 정말 울 타 리 를 벗 어 나 유연 하 게 응용 할 수 있다!
WPF 가 일상적으로 개발 하 는 플 라 워 컨트롤 기능 확장 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 WPF 플 라 워 컨트롤 기능 확장 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기