当前位置: 首页 > news >正文

个人所得税app下载沈阳百度seo排名优化软件

个人所得税app下载,沈阳百度seo排名优化软件,软件开发商是什么意思,萍乡公司做网站WPF中在MVVM模式下实现导航功能 一、利用TabControl 使用场景&#xff1a;项目小&#xff0c;不用考虑内存开销的问题。 实现方式1-手动指定ViewModel 分别定义3个UserControl作为View用于演示 <UserControl...><Grid><StackPanel Orientation"Vertic…

WPF中在MVVM模式下实现导航功能

一、利用TabControl

使用场景:项目小,不用考虑内存开销的问题。
splashScreen

实现方式1-手动指定ViewModel

  1. 分别定义3个UserControl作为View用于演示
 <UserControl...><Grid><StackPanel Orientation="Vertical"><TextBlockHorizontalAlignment="Center"VerticalAlignment="Top"Text="Page 1" /><TextBlockd:Text="Page 1"FontSize="50"Text="{Binding PageMessage}" /></StackPanel></Grid></UserControl>
  1. 分别定义ViewModel
 public abstract class PageViewModelBase {public string? Header { get; set; }}public class MainViewModel {public List<PageViewModelBase> ViewModels { get; }public MainViewModel(Page1ViewModel p1, Page2ViewModel p2, Page3ViewModel p3){ViewModels = new List<PageViewModelBase> { p1, p2, p3 };}}public class Page1ViewModel : PageViewModelBase{public Page1ViewModel() => Header = "Page 1";public string PageMessage { get; set; } = "Hello, Page 1";}public class Page2ViewModel : PageViewModelBase{public Page2ViewModel() => Header = "Page 2";public string PageMessage { get; set; } = "Hello, Page 2";}public class Page3ViewModel : PageViewModelBase{public Page3ViewModel() => Header = "Page 3";public string PageMessage { get; set; } = "Hello, Page 3";}
  1. 在MainWindow上定义Tabcontrol
 <Window...><Grid><TabControl ItemsSource="{Binding ViewModels}"><TabItem Header="Pag1"><view:Page1><view:Page1.DataContext><local:Page1ViewModel /></view:Page1.DataContext></view:Page1></TabItem><TabItem Header="Pag2"><view:Page1><view:Page1.DataContext><local:Page2ViewModel /></view:Page1.DataContext></view:Page1></TabItem><TabItem Header="Pag3"><view:Page1><view:Page1.DataContext><local:Page3ViewModel /></view:Page1.DataContext></view:Page1></TabItem></TabControl></Grid></Window>

这种方式需要手动指定每个View的ViewModel

实现方式2-利用ItemTemplate

  1. 在MainViewModel中声明一个ViewModel列表
public class MainViewModel 
{public List<PageViewModelBase> ViewModels { get; }public MainViewModel(Page1ViewModel p1, Page2ViewModel p2, Page3ViewModel p3){ViewModels = new List<PageViewModelBase> { p1, p2, p3 };}
}
  1. 在MainWindow中为TabControl指定ItemTemplate,上一步声明的ViewModel列表作为 TabControl 的 ItemsSource;为 TabControl.Resources 添 加多个 DataTemplate,指定 VM 对应什么样的 Page
<Window d:DataContext="{d:DesignInstance Type=local:MainViewModel}"....><Grid><TabControl ItemsSource="{Binding ViewModels}"><TabControl.ItemTemplate><DataTemplate><TextBlock Text="{Binding Header}"/></DataTemplate></TabControl.ItemTemplate><TabControl.Resources><DataTemplate DataType="{x:Type local:Page1ViewModel}"><view:Page1/></DataTemplate><DataTemplate DataType="{x:Type local:Page2ViewModel}"><view:Page2/></DataTemplate><DataTemplate DataType="{x:Type local:Page3ViewModel}"><view:Page3/></DataTemplate></TabControl.Resources>   </TabControl></Grid>
</Window>

这样的好处是自动会为不同的View绑定了相应的ViewModel。

小技巧:在xaml中加上了d:DataContext="{d:DesignInstance Type=local:MainViewModel},这样在写Binding的时候就有了智能提示。

以上两种方式均可结合依赖注入的方式来实现

二、自定义NavigationService服务

splashScreen

  1. 实现一个NavigationService服务,并作为单例
 class NavigationService{//设置一个单例服务public static NavigationService Instance { get; private set; } = new NavigationService();//声明一个事件,当更改CurrentViewModel时触发public event Action? CurrentViewModelChanged;//设置一个当前VM的属性,并在属性改变时触发CurrentViewModelChangedprivate ViewModelBase? currentViewModel;public ViewModelBase? CurrentViewModel{get => currentViewModel;set{currentViewModel = value;CurrentViewModelChanged?.Invoke();}}//页面导航方法,给CurrentViewModel赋值,触发CurrentViewModelChanged事件public void NavigateTo(ViewModelBase viewModel)=>CurrentViewModel = viewModel;}
  1. 设置MainViewModel中的CurrentViewModel属性
 public class ViewModelBase : ObservableObject{}public partial class MainViewModel : ViewModelBase{[ObservableProperty]private ViewModelBase? currentViewModel;//当前的VMpublic MainViewModel(){//为事件绑定委托方法,设置CurrentVM和NavigationService中的CurrentVM保持一致NavigationService.Instance.CurrentViewModelChanged += () =>{CurrentViewModel = NavigationService.Instance.CurrentViewModel;};//调用导航方法NavigationService.Instance.NavigateTo(new LoginViewModel());}}

其他两个ViewModel分别为

 public partial class LoginViewModel : ViewModelBase{[ObservableProperty]string? userName = "Sean";[RelayCommand]void Login(){NavigationService.Instance.NavigateTo(new HomeViewModel());}}public partial class HomeViewModel : ViewModelBase{[ObservableProperty]string? userName;[RelayCommand]void Logout(){NavigationService.Instance.NavigateTo(new LoginViewModel());}}
  1. 使用ContentControl作为MainWindow上不同页面载体显示内容,并借助DataTemplate来实现View和ViewModel的映射
 <Window ...><ContentControl Content="{Binding CurrentViewModel}"><ContentControl.Resources><DataTemplate DataType="{x:Type vm:LoginViewModel}"><view:Login /></DataTemplate><DataTemplate DataType="{x:Type vm:HomeViewModel}"><view:Home /></DataTemplate></ContentControl.Resources></ContentControl></Window>

在ContentControl.Resources中设置DataTemplate,根据DataType自动选择相应的VM,这样做的好处是会自动将View和VM进行了绑定。

改进

  1. 单例方式可以采用依赖注入的方式来实现
  2. 在NavigationService服务中,可以改进页面导航的方法
public void NavigateTo<T>() where T : ViewModelBase=> CurrentViewModel = App.Current.Services.GetService<T>();//在调用导航方法时可以使用
navigationService.NavigateTo<HomeViewModel>();

三、借助ValueConverter

实现上一章节的功能,这种方法本质上是通过View来自动绑定VM。

  1. 定义Page的枚举
 public enum ApplicationPage{Empty,Login,Home}
  1. 定义各ViewModel
 public class ViewModelBase : ObservableObject{}public partial class MainViewModel : ViewModelBase{//MainViewModel中的CurrentPage是一个枚举类型[ObservableProperty]ApplicationPage currentPage;public MainViewModel(){CurrentPage = ApplicationPage.Login;}}public partial class LoginViewModel : ViewModelBase{public string UserName { get; set; } = "AngelSix";[RelayCommand]void Login(){var mainVM= App.Current.MainWindow.DataContext as MainViewModel;mainVM!.CurrentPage = ApplicationPage.Home;}}public partial class HomeViewModel : ViewModelBase{[RelayCommand]void Logout(){var mainVM = App.Current.MainWindow.DataContext as MainViewModel;mainVM!.CurrentPage = ApplicationPage.Login;}}
  1. 定义Page基类和各个Page

    这种方法本质上是通过View来自动绑定VM,所以在此处使用泛型

 public abstract class BasePage<VM> : UserControl where VM : ViewModelBase, new(){public BasePage(){DataContext = new VM();}}
  • 实现Home页面

将Home.xaml.cs中的继承删掉,以为它和Home.xaml相互为分部类,只在一个分部类上实现继承就可以。

 <local:BasePage x:TypeArguments="vm:HomeViewModel"...><!--x:TypeArguments指定泛型--><Grid><TextBlock HorizontalAlignment="Center"VerticalAlignment="Center"Text="Home"FontSize="32" /><Button Margin="10" Grid.Row="1"HorizontalAlignment="Right"VerticalAlignment="Bottom"Content="Logout"Command="{Binding LogoutCommand}" /></Grid></local:BasePage>
  • 实现Login页面

方法和实现Home页面方法相同

 <local:BasePagex:TypeArguments="vm:LoginViewModel" ...><Grid><BorderPadding="10"HorizontalAlignment="Center"VerticalAlignment="Center"BorderBrush="LightGray"BorderThickness="1"CornerRadius="10"><StackPanel Width="300"><TextBlock HorizontalAlignment="Center" FontSize="28">Login</TextBlock><Separator Margin="0,10" /><TextBlock>User name:</TextBlock><TextBoxMargin="0,10"InputMethod.IsInputMethodEnabled="False"Text="{Binding UserName}" /><TextBlock>Password:</TextBlock><PasswordBox Margin="0,10" Password="123456" /><Button Command="{Binding LoginCommand}" Content="Login" /></StackPanel></Border></Grid></local:BasePage>
  1. 定义PageViewConverter

    public class PageViewConverter : IValueConverter
    {public object Convert(object value, Type targetType, object parameter, CultureInfo culture){switch ((ApplicationPage)value){case ApplicationPage.Empty:return new TextBlock { Text = "404 Not Found" };case ApplicationPage.Login:return new Login();case ApplicationPage.Home:return new Home();default:throw new ArgumentException("Invalid value passed to ApplicationPageViewConverter");}}public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){throw new NotImplementedException();}
    }
    
  2. 完成MainWindow

 <Window ...><Window.DataContext><local:MainViewModel/></Window.DataContext><Window.Resources><share:PageViewConverter x:Key="pageConv"/></Window.Resources><ContentControl Content="{Binding CurrentPage,Converter={StaticResource pageConv}}"/></Window>

改进

  1. 可以结合依赖注入的方式来实现

  2. 导航方法可以封装为一个NavigationService服务

 //封装服务class NavigationService{public static NavigationService Instance { get; } = new NavigationService();private MainViewModel mainVM;public void Navigate(ApplicationPage page){if (mainVM == null){mainVM = (MainViewModel)App.Current.MainWindow.DataContext;}mainVM.CurrentPage = page;}}//原来的方式void Logout(){var mainVM = App.Current.MainWindow.DataContext as MainViewModel;mainVM!.CurrentPage = ApplicationPage.Login;}//使用封装好的服务void Login(){NavigationService.Instance.Navigate(ApplicationPage.Login);}

四、使用Frame和NavigationService

实现上一章节功能,本质上是使用依赖注入的方式将View和ViewModel进行绑定,并利用Frame的自带的Navigate方法进行导航

  1. 定义ViewModel
 public class ViewModelBase : ObservableObject{}public partial class MainWindowViewModel : ViewModelBase{private readonly NavigationService navigationService;//依赖注入public MainWindowViewModel(NavigationService navigationService){this.navigationService = navigationService;}[RelayCommand]void Loaded(){  //navigationService实现的导航方法navigationService.Navigate<LoginViewModel>();}}public partial class HomeViewModel : ViewModelBase{[ObservableProperty]string? userName;}public partial class LoginViewModel : ViewModelBase{private readonly NavigationService navigationService;//依赖注入public string UserName { get; set; } = "Sergio";public LoginViewModel(NavigationService navigationService){this.navigationService = navigationService;}[RelayCommand]void Login(){   //navigationService实现的导航方法,此处进行了传参navigationService.Navigate<HomeViewModel>(new Dictionary<string, object?>{[nameof(HomeViewModel.UserName)] = UserName});}}
  1. 定义View

主窗口,使用Behaviors实现mvvm模式

<Windowxmlns:b="http://schemas.microsoft.com/xaml/behaviors"><b:Interaction.Triggers><b:EventTrigger><b:InvokeCommandAction Command="{Binding LoadedCommand}" /></b:EventTrigger></b:Interaction.Triggers>
</Window>

主窗口后台类

public partial class MainWindow : Window
{public MainWindow(MainWindowViewModel viewModel,Frame frame){InitializeComponent();DataContext = viewModel;AddChild(frame);}
}

其他View

<!--使用Page来承载内容-->
<Page ...><Grid><TextBlock HorizontalAlignment="Center"VerticalAlignment="Center"d:Text="Hello, world!"Text="{Binding UserName, StringFormat='Hello, {0}!'}"FontSize="32" /></Grid>
</Page><Page ...><Grid><Border Padding="10"HorizontalAlignment="Center"VerticalAlignment="Center"BorderThickness="1"CornerRadius="10"BorderBrush="LightGray"><StackPanel Width="300"><TextBlock HorizontalAlignment="Center" FontSize="28">Login</TextBlock><Separator Margin="0,10" /><TextBlock>User name:</TextBlock><TextBox Margin="0,10" Text="{Binding UserName}" InputMethod.IsInputMethodEnabled="False" /><TextBlock>Password:</TextBlock><PasswordBox Margin="0,10" Password="123456" /><Button Content="Login" Command="{Binding LoginCommand}" /></StackPanel></Border></Grid>
</Page>

在后台类中使用依赖注入的方式定义DataContext

public Home(HomeViewModel viewModel)
{InitializeComponent();DataContext = viewModel;
}public Login(LoginViewModel viewModel)
{InitializeComponent();DataContext = viewModel;
}
  1. 实现NavigationService
 public class NavigationService{//注册了单例的Frameprivate readonly Frame? mainFrame;public NavigationService(Frame? frame){mainFrame = frame;//要使用LoadCompleted事件mainFrame.LoadCompleted += MainFrame_LoadCompleted;}private void MainFrame_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e){if (e.ExtraData is not Dictionary<string,object?> extraData){return;}if ((mainFrame?.Content as FrameworkElement)?.DataContext is not ViewModelBase vm){return;}foreach (var item in extraData){//为每个属性赋值vm.GetType().GetProperty(item.Key)?.SetValue(vm, item.Value);}}//根据VM类型查找View,要注意VM和View的命名规范private Type? FindView<T>(){return Assembly.GetAssembly(typeof(T))?.GetTypes().FirstOrDefault(x => x.Name == typeof(T).Name.Replace("ViewModel", ""));}public void Navigate<T>(Dictionary<string,object?>? extraData=null) where T:ViewModelBase{var viewType = FindView<T>();if (viewType is null)return;var page = App.Current.Services.GetService(viewType) as Page;//利用Frame的Navigate方法进行导航和传参mainFrame?.Navigate(page,extraData);}   }
  1. 注册需要的类,此案例在App.cs中进行注册
 public partial class App : Application{public IServiceProvider Services { get; }public static new App Current => (App)Application.Current;public App(){var container = new ServiceCollection();container.AddSingleton(_ => new Frame { NavigationUIVisibility = NavigationUIVisibility.Hidden });container.AddSingleton<MainWindow>();container.AddSingleton<MainWindowViewModel>();container.AddTransient<Login>();container.AddTransient<Home>();container.AddTransient<LoginViewModel>();container.AddTransient<HomeViewModel>();container.AddSingleton<NavigationService>();Services = container.BuildServiceProvider();}protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);MainWindow = Services.GetRequiredService<MainWindow>();MainWindow.Show();}}

文章转载自:
http://ahitophal.xqwq.cn
http://karaganda.xqwq.cn
http://decurved.xqwq.cn
http://ballute.xqwq.cn
http://vespiform.xqwq.cn
http://pigmentary.xqwq.cn
http://ultramicro.xqwq.cn
http://jacal.xqwq.cn
http://roundhouse.xqwq.cn
http://crassulaceous.xqwq.cn
http://backboned.xqwq.cn
http://hemoblast.xqwq.cn
http://synchronoscope.xqwq.cn
http://ascertainment.xqwq.cn
http://stitch.xqwq.cn
http://bliss.xqwq.cn
http://flavoring.xqwq.cn
http://stewbum.xqwq.cn
http://varvel.xqwq.cn
http://subincandescent.xqwq.cn
http://etiolate.xqwq.cn
http://apocrypha.xqwq.cn
http://eboat.xqwq.cn
http://valentina.xqwq.cn
http://paracetaldehyde.xqwq.cn
http://alastrim.xqwq.cn
http://tsarevitch.xqwq.cn
http://pagan.xqwq.cn
http://equability.xqwq.cn
http://employer.xqwq.cn
http://clearinghouse.xqwq.cn
http://machisma.xqwq.cn
http://overdrifted.xqwq.cn
http://borak.xqwq.cn
http://drosera.xqwq.cn
http://liberticide.xqwq.cn
http://revalve.xqwq.cn
http://deviant.xqwq.cn
http://eurystomatous.xqwq.cn
http://betrothed.xqwq.cn
http://dioxirane.xqwq.cn
http://kcmg.xqwq.cn
http://lawn.xqwq.cn
http://maratha.xqwq.cn
http://gossipist.xqwq.cn
http://plenipotence.xqwq.cn
http://embryogenesis.xqwq.cn
http://basidium.xqwq.cn
http://sixpence.xqwq.cn
http://andy.xqwq.cn
http://solubilise.xqwq.cn
http://antagonistical.xqwq.cn
http://basilian.xqwq.cn
http://thrustor.xqwq.cn
http://memory.xqwq.cn
http://girandola.xqwq.cn
http://allergist.xqwq.cn
http://sceptic.xqwq.cn
http://jennings.xqwq.cn
http://underprivilege.xqwq.cn
http://plummer.xqwq.cn
http://matadora.xqwq.cn
http://sojourner.xqwq.cn
http://trommel.xqwq.cn
http://tarpan.xqwq.cn
http://tutee.xqwq.cn
http://procne.xqwq.cn
http://broadish.xqwq.cn
http://purga.xqwq.cn
http://cognition.xqwq.cn
http://mithras.xqwq.cn
http://zoril.xqwq.cn
http://shy.xqwq.cn
http://sixfold.xqwq.cn
http://aphaeresis.xqwq.cn
http://tankette.xqwq.cn
http://pollenosis.xqwq.cn
http://grivet.xqwq.cn
http://lanate.xqwq.cn
http://fastigiate.xqwq.cn
http://tricuspidate.xqwq.cn
http://bedewed.xqwq.cn
http://wilno.xqwq.cn
http://superspace.xqwq.cn
http://deoxidation.xqwq.cn
http://proscenium.xqwq.cn
http://bodyguard.xqwq.cn
http://nuke.xqwq.cn
http://minim.xqwq.cn
http://endorser.xqwq.cn
http://supernutrition.xqwq.cn
http://tdn.xqwq.cn
http://affirmably.xqwq.cn
http://acupuncturist.xqwq.cn
http://percolation.xqwq.cn
http://punt.xqwq.cn
http://airdrome.xqwq.cn
http://rumen.xqwq.cn
http://kryzhanovskite.xqwq.cn
http://kolo.xqwq.cn
http://www.hrbkazy.com/news/66362.html

相关文章:

  • 做纸巾定制的网站24小时自助下单平台网站便宜
  • 时时彩网站开发流程网站优化 推广
  • 自己做网站花钱么网络工程师培训机构排名
  • 深圳市政府门户网站功能建设最近新闻今日头条
  • 广告设计教学大纲深圳推广优化公司
  • 视频网站怎么做统计注册网址在哪里注册
  • 做网站服务器用国外的seo站长工具综合查询
  • 服务器租用公司文明seo
  • 有哪些做壁纸的网站aso优化的主要内容为
  • 长沙做网站建设价格我要看今日头条
  • 多少钱算诈骗上海网站seo排名优化
  • 网站推广的搜索引擎推广优化营商环境的意义
  • 12306网站如何做解绑手机优化专家
  • 网站尾部一般怎么做网络推广长沙网络推广
  • 东莞市官网网站建设平台电商运营平台
  • 网站制作教程设计院智慧软文网站
  • 07年做网站想做app推广项目在哪找
  • 做网站配置好了找不到服务器绍兴seo推广
  • ip开源网站fpga可以做点什么用网络推广方案七步法
  • 做网站链接域名是什么意思呢
  • 十堰高端网站建设全球网站流量查询
  • 网站建设的未来今日新闻摘抄十条简短
  • 打开云南省住房和城乡建设厅网站网站推广和seo
  • 网站cn和com有什么区别app线下推广怎么做
  • 搜索引擎营销名词解释黑河seo
  • 门户网站建设评估如何建立自己的网络销售
  • 请人制作一个网站需要多少钱seo排名赚
  • 网站视频外链怎么做2023年百度小说风云榜
  • 夜晚很晚视频免费素材网站网站制作流程
  • 百度做网站投广告网址大全网站