c\#WPF 구현 Windows 자원 관리자(소스 코드)
전체적인 구 조 를 본 격 적 으로 소개 하기 전에 먼저 전체적인 구 조 를 살 펴 보고 이에 대해 대략적인 이 해 를 가진다.
전체 화면 은 큰 측면 에서 볼 때 주로 세 가지 측면 을 포함한다.하 나 는 파일 과 폴 더 디 스 플레이 구역,2 네 비게 이 션 구역,3 경로 디 스 플레이 구역 이다.사실은 전체 화면 에서 2 와 3 은 모두 1 을 중심 으로 조작 되 고 세 구역 간 의 결합 성 이 매우 높 기 때문에 일반적인 방법 은 세 부분 으로 나 뉘 어 세 개의 UserControl 이다.또한 하나의 ViewModel 에 연결 하면 전체적인 차원 도 뚜렷 해진 다.단점 은 하나의 ViewModel 에 코드 가 너무 많 고 직책 이 매우 크다 는 것 이다.그래서 이 DEMO 에서 세 부분 을 나 누고 세 개의 ViewModel 로 세 개의 View 안의 내용 을 조작 하려 고 시도 했다.전체적으로 실현 하면 부족 한 점도 있다.그것 은 바로 문 제 를 복잡 하 게 만 들 기 쉽다 는 것 이다.한 가지 유형 에서 완성 할 수 있 는 많은 일 들 이 최종 적 으로 각 종류 와 유형 간 의 결합 을 통 해 이 루어 져 야 한다.그래서 이 DEMO 를 통 해 자신 이 더 많은 사 고 를 하고 소프트웨어 의 디자인 에서 경험 을 많이 하고 소프트웨어 의 입도 문 제 를 잘 파악 할 수 있 기 를 바란다.다음은 소프트웨어 의 구체 적 인 내용 에 대해 깊이 분석 해 보 자.
제1 부분:FileList
이 부분 은 전체 파일 과 폴 더 의 디 스 플레이 부분 으로 재삼 저울질 해 사용자 정의 DataGrid 방식 으로 전체 부분 을 보 여주 기로 했다.
<UserControl x:Class="FileSelectorDemo.Views.FileList"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:converter="clr-namespace:FileSelectorDemo.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:defines="clr-namespace:FileSelectorDemo.Defines"
xmlns:local="clr-namespace:FileSelectorDemo.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<converter:CountToVisibilityConverter x:Key="CountToVisibilityConverter"></converter:CountToVisibilityConverter>
<converter:TypeToVisibleConverter x:Key="TypeToVisibleConverter"></converter:TypeToVisibleConverter>
<converter:TypeToCollapsedConverter x:Key="TypeToCollapsedConverter"></converter:TypeToCollapsedConverter>
<converter:CollectionSelectedCountConverter x:Key="CollectionSelectedCountConverter"></converter:CollectionSelectedCountConverter>
</UserControl.Resources>
<Grid>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid>
<StackPanel Orientation="Vertical">
<DataGrid x:Name="fileList" Style="{StaticResource DefaultDataGrid}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" defines:MouseDoubleClick.Command="{Binding OpenCurrentDirectory}"
defines:MouseDoubleClick.CommandParameter="{Binding SelectedItem,RelativeSource={RelativeSource Self}}" IsReadOnly="True"
defines:MouseLeftButtonUpClick.Command="{Binding SelectCurrentFileListItem}" ItemsSource="{Binding CurrentFileList}" CanUserAddRows="False" AutoGenerateColumns="False" GridLinesVisibility="None">
<DataGrid.Columns>
<DataGridTemplateColumn MinWidth="60">
<DataGridTemplateColumn.Header>
<CheckBox Content=" " Margin="2" FontSize="12" HorizontalAlignment="Center" VerticalAlignment="Center" IsChecked="{Binding DataContext.IsStateCheckAll,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}"></CheckBox>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text=" " FontSize="12" Foreground="Black" Visibility="{Binding CurrentType,Converter={StaticResource TypeToCollapsedConverter}}" HorizontalAlignment="Left" VerticalAlignment="Center" ></TextBlock>
<CheckBox IsChecked="{Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsThreeState="False" IsHitTestVisible="False" Visibility="{Binding CurrentType,Converter={StaticResource TypeToVisibleConverter}}" HorizontalAlignment="Left" VerticalAlignment="Center" ToolTip=" "></CheckBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header=" " >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
<Image Source="{Binding Icon}" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center"></Image>
<TextBlock Text="{Binding Name}" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header=" " Binding="{Binding CreateTime}"/>
<DataGridTextColumn Header=" " Binding="{Binding CurrentType}"/>
<DataGridTextColumn Header=" " Binding="{Binding Size}"/>
</DataGrid.Columns>
</DataGrid>
<TextBlock Margin="2 5" HorizontalAlignment="Left" VerticalAlignment="Center" >
<Run> </Run>
<Run Text="{Binding CurrentFileList.Count,Mode=OneWay}"></Run>
<Run> </Run>
<Run>( </Run>
<Run Text="{Binding CurrentFileList,Converter={StaticResource CollectionSelectedCountConverter},Mode=OneWay}"></Run>
<Run> )</Run>
</TextBlock>
</StackPanel>
<TextBlock Text=" " Visibility="{Binding CurrentFileList.Count,Converter={StaticResource CountToVisibilityConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</Grid>
</ScrollViewer>
</Grid>
</UserControl>
여 기 는 모두 일반적인 정의 입 니 다.여 기 는 더 이상 군말 하지 않 겠 습 니 다.DataGrid 스타일 은 Themes 폴 더 아래 의 CustomDataGrid 스타일 을 참조 하 는 것 입 니 다.이 안 에는 사용자 정의 ScrollViewer 스타일 과 ScrollBar 스타일 도 포함 되 어 있 습 니 다.독자 도 생각 할 수 있 습 니 다.또한 아래 의 몇 가지 속성 을 설정 하 는 데 주의해 야 합 니 다.1 IsReadOnly="True"라 는 속성 은 마우스 클릭 시 내부 의 TextBox 를 표시 하지 않 고 사용자 가 마음대로 편집 할 수 없 도록 보장 합 니 다.
2 GridLines Visibility="None"는 전체 DataGrid 가 분할 선 을 표시 하지 않 고 Windows 의 네 이 티 브 스타일 에 더욱 가 깝 게 할 수 있 습 니 다.
3 CanUser AddRows="False"라 는 속성 도 매우 중요 합 니 다.그렇지 않 으 면 전체 디 스 플레이 영역 아래 에 한 줄 이 더 나 오고 사용자 가 클릭 할 때 줄 이 추 가 됩 니 다.
4 AutoGenerate Columns="False"는 비교적 익숙 하 며,일반적으로 열 을 자동 으로 추가 하지 못 하 게 합 니 다.
5 Selection Unit="FullRow"는 마 우 스 를 클릭 할 때 선택 하 는 단 위 는 줄 전체 이지 그 중의 셀 이나 다른 것 이 아니 라 다른 몇 개의 매 거 진 값 에 대해 독자 도 관련 된 이 해 를 찾 아 볼 수 있다 는 것 을 나타 낸다.
6 Selection Mode="Extended"는 여러 옵션 을 허용 합 니 다.마우스 의 Ctrl 키 를 눌 러 클릭 할 때 여러 대상 을 선택 할 수 있 습 니 다.
7 마지막 으로 DataGrid 를 설정 하 는 가상 화 용기 입 니 다.구체 적 인 설정 방법 은:
<Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"></Setter>
<Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling" />
WPF 의 Virtualizing StackPanel.VirtualizationMode 추가 속성 지정 ItemsControl 판 넬 의 하위 항목 을 어떻게 가상 화 합 니까?기본적으로 Virtualizing StackPanel 보 이 는 항목 마다 용 기 를 만 들 고 필요 하지 않 을 때(예 를 들 어 항목 이 보기 밖으로 굴 러 갈 때)용 기 를 버 립 니 다....해 야 한다 ItemsControl 여러 항목 을 포함 할 때,항목 용 기 를 만 들 고 폐기 하 는 과정 은 성능 에 부정적인 영향 을 미 칠 수 있 습 니 다.하면,만약,만약... VirtualizingStackPanel.VirtualizationMode 으로 설정 Recycling,VirtualizingStackPanel 매번 새로운 용 기 를 만 드 는 것 이 아니 라 항목 용 기 를 다시 사용 합 니 다.이것 은 MSDN 에서 발췌 한 관련 자료 입 니 다.우리 가 불 러 온 DataGrid 의 항목 이 많 지 않 기 때문에 충분 한 경우 효과 가 더욱 뚜렷 해 질 수 있 습 니 다.더 많은'가상 화'기술 에 대해 서 는 더 많은 자 료 를 참고 할 수 있 습 니 다.여기 서 중요 한 것 은 DataGridRow 를 두 번 눌 렀 을 때 해당 하 는 하위 폴 더 를 열 고 눌 렀 을 때 현재 DataGridRow 를 선택 하 는 것 입 니 다.여기 서 이벤트 에 대한 바 인 딩 은 System.Windows.Interactivity 라 는 방식 으로 이 벤트 를 연결 하 는 것 이 아 닙 니 다.여기 서 우 리 는 추가 속성 을 사용자 정의 하여 이 루어 집 니 다.마우스 왼쪽 단 추 를 더 블 클릭 하 는 것 을 예 로 들 어 설명 한다.
여기 서 설명 해 야 할 것 은 OnMouse DoubleClick 에서 현재 마우스 가 클릭 한 Point 를 통 해 최종 DataGridRow 를 찾 은 다음 에 연 결 된 Command 이 벤트 를 터치 하 는 것 입 니 다.프론트 뷰 에서 저 희 는 해당 하 는 ICommand 에 연결 하면 됩 니 다.
public class MouseDoubleClick
{
public static DependencyProperty CommandProperty =
DependencyProperty.RegisterAttached("Command",
typeof(ICommand),
typeof(MouseDoubleClick),
new UIPropertyMetadata(CommandChanged));
public static DependencyProperty CommandParameterProperty =
DependencyProperty.RegisterAttached("CommandParameter",
typeof(object),
typeof(MouseDoubleClick),
new UIPropertyMetadata(null));
public static void SetCommand(DependencyObject target, ICommand value)
{
target.SetValue(CommandProperty, value);
}
public static void SetCommandParameter(DependencyObject target, object value)
{
target.SetValue(CommandParameterProperty, value);
}
public static object GetCommandParameter(DependencyObject target)
{
return target.GetValue(CommandParameterProperty);
}
private static void CommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
{
Control control = target as Control;
if (control != null)
{
if ((e.NewValue != null) && (e.OldValue == null))
{
control.MouseDoubleClick += OnMouseDoubleClick;
}
else if ((e.NewValue == null) && (e.OldValue != null))
{
control.MouseDoubleClick -= OnMouseDoubleClick;
}
}
}
private static void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
DataGrid datagrid = sender as DataGrid;
Point point = e.GetPosition(datagrid);
IInputElement obj = datagrid.InputHitTest(point);
DependencyObject target = obj as DependencyObject;
while (target != null)
{
if (target is DataGridRow)
{
ICommand command = (ICommand)datagrid.GetValue(CommandProperty);
object commandParameter = datagrid.GetValue(CommandParameterProperty);
if (null != commandParameter)
{
command.Execute(commandParameter);
}
break;
}
target = VisualTreeHelper.GetParent(target);
}
}
}
defines:MouseDoubleClick.Command="{Binding OpenCurrentDirectory}" defines:MouseDoubleClick.CommandParameter="{Binding SelectedItem,RelativeSource={RelativeSource Self}}"
그 중에서 우 리 는 네 임 스페이스 defines 를 정의 해 야 한다.이런 방법 은 우리 가 View 층 의 각종 사건 을 연결 하 는 데 새로운 방식 을 제공 할 수 있다.이것 은 우리 가 끊임없이 정리 하고 분석 해 야 할 부분 이다.제2 부분:Navigation
이 부분 은 내 비게 이 션 표시 줄 의 부분 입 니 다.앞으로,뒤로,위로 빠 른 동작 을 통 해 폴 더 를 빠르게 전환 하여 전환 경 로 를 쉽게 만 들 수 있 습 니 다.이 부분 은 최근 에 항목 을 탐색 하 는 기능 을 다시 말 해 야 합 니 다.사용자 가 최근 에 탐색 한 10 개의 디 렉 터 리(개발 자 사용자 정의)를 저장 할 수 있 습 니 다.따라서 사용자 가 서로 다른 경 로 를 신속하게 전환 하 는 데 편리 합 니 다.이것 은 ToggleButton 과 Popup 이라는 전형 적 인 조합 을 통 해 이 루어 진 것 입 니 다.구체 적 으로 실현 하려 면 소스 코드 를 참고 하 십시오.이 부분 에 서 는 마우스 가 서로 다른 위치 로 이동 할 때 바 인 딩 된 아이콘 이 앞으로 또는 뒤로 또는 선택 상 태 를 바 꿀 수 있 습 니 다.이것 은 모든 모델 을 연결 하 는 currentDirection 을 통 해 이 루어 집 니 다.여기 서 DataTrigger 의 사용 방법 을 중점적으로 파악 해 야 합 니 다.
<Popup Placement="Bottom" PlacementTarget="{Binding ElementName=NavigationPanel}" StaysOpen="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
IsOpen="{Binding IsChecked,ElementName=History,Mode=OneWay}" PopupAnimation="Slide">
<ItemsControl Background="#f5f5f5" BorderBrush="Gray" BorderThickness="1" Padding="0"
ItemsSource="{Binding AttachedDataContext.DirectoryHistory,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}}}">
<ItemsControl.Template>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<Border x:Name="outer" Padding="0 2" Background="#f5f5f5">
<StackPanel Orientation="Vertical" IsItemsHost="True"></StackPanel>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button x:Name="radioButton" Command="{Binding AttachedDataContext.SwitchDirectory,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type UserControl}}}"
CommandParameter="{Binding}">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="bg" Padding="0" Background="#f5f5f5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
<Path x:Name="path" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center" Stroke="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}" Width="24" Height="24"
Opacity="0" StrokeThickness="2" StrokeLineJoin="Round" SnapsToDevicePixels="False">
</Path>
<Image Source="{Binding Icon}" Width="24" Height="24" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center"></Image>
<TextBlock Text="{Binding Name}" Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding CurrentDirection}" Value=" ">
<Setter Property="Opacity" Value="1" TargetName="path"></Setter>
<Setter Property="Data" Value="M 2,10 L 8,14 18,6" TargetName="path"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CurrentDirection}" Value=" ">
<Setter Property="Opacity" Value="0" TargetName="path"></Setter>
<Setter Property="Data" Value="M8,6 L1,11 8,16 M0,11 L15,11" TargetName="path"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding CurrentDirection}" Value=" ">
<Setter Property="Opacity" Value="0" TargetName="path"></Setter>
<Setter Property="Data" Value="M8,6 L15,11 8,16 M0,11 L15,11" TargetName="path"></Setter>
</DataTrigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#91c9f7" TargetName="bg"></Setter>
<Setter Property="Opacity" Value="1" TargetName="path"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Popup>
세 번 째 부분:BreadCrumbView이 부분 은 현재 폴 더 경 로 를 표시 하고 빠 른 전환 준 비 를 하 는 데 사 용 됩 니 다.이 부분 은 하나의 조합 컨트롤 입 니 다.주로 Items Control 과 ToggleButton,Popup 을 통 해 이 루어 집 니 다.이 부분 에서 주의해 야 할 것 은 이 안에 연 결 된 명령 과 방법 은 모두 FileList 의 ViewModel 에서 정 의 된 것 입 니 다.코드 재 활용 을 최대한 실현 하기 위해 서 입 니 다.이러한 방식 을 통 해 우 리 는 수시로 FileListView Model 의 내용 을 방문 할 수 있어 야 한 다 는 것 을 알 게 될 때 가 많 습 니 다.이것 은 전체 DEMO 에서 가장 중요 한 부분 이기 때문에 어떻게 해야만 FileListView Model 의 내용 을 인용 할 수 있 습 니까?
public partial class BreadCrumbView : UserControl
{
public BreadCrumbView()
{
InitializeComponent();
Loaded +=new RoutedEventHandler(BreadCrumbView_Loaded);
}
private void BreadCrumbView_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = new ViewModels.BreadCrumbViewModel(AttachedDataContext);
}
/// <summary>
/// FileList DataContext
/// </summary>
public object AttachedDataContext
{
get { return (object)GetValue(AttachedDataContextProperty); }
set { SetValue(AttachedDataContextProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AttachedDataContextProperty =
DependencyProperty.Register("AttachedDataContext", typeof(object), typeof(BreadCrumbView), new PropertyMetadata(null));
}
AttachedDataContext 대상 을 정의 함으로써 우 리 는 FileListViewModel 에서 정의 한 속성 을 각 ViewModel 에 분산 시 킬 수 있 습 니 다.그러면 어느 정도 에 FileListViewModel 에서 코드 가 너무 많 고 직책 이 너무 무 거 운 문 제 를 피 할 수 있 습 니 다.그러나 동시에 우 리 는 서로 간 의 결합 이 너무 크 면이런 방식 을 사용 하면 코드 간 의 복잡 도 를 가중 시 킬 수 있다.가끔 은 Action 이나 사건 등 방식 으로 ViewModel 간 의 상호작용 과 통신 을 해 야 하기 때문에 여기 서 우 리 는 비교적 복잡 한 프로젝트 에서 프레임 워 크 를 사용 하 는 중요성 을 말 할 수 밖 에 없다.예 를 들 어 Prism 또는 Caliburn.Micro 등 구 조 는 전체 소프트 메 틸 구 조 를 더욱 명확 하고 명확 하 게 보이 게 할 수 있다.이것 은 소프트웨어 의 모듈 화 와 유연성 을 더욱 향상 시 키 기 위해 서 이다.이 DEMO 의 분석 을 통 해 우 리 는 끊 임 없 는 실천 에서 이런 유형의 경험 을 정리 하여 전체 소프트웨어 를 더욱 합 리 적 으로 보이 고 최종 적 으로 소프트웨어 의 구조 사상 에 대해 깊이 있 게 이해 할 수 있 도록 해 야 한다.
마지막 으로 전체 데모 가 필요 합 니 다여 기 를 클릭 하여 다운로드 하 세 요!
이상 은 c\#WPF 가 Windows 자원 관리자(원본 코드 첨부)를 실현 하 는 상세 한 내용 입 니 다.c\#WPF 가 Windows 자원 관리 자 를 실현 하 는 것 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C#Task를 사용하여 비동기식 작업을 수행하는 방법라인이 완성된 후에 이 라인을 다시 시작할 수 없습니다.반대로 조인(Join)만 결합할 수 있습니다 (프로세스가 현재 라인을 막습니다). 임무는 조합할 수 있는 것이다. 연장을 사용하여 그것들을 한데 연결시키는 것이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.