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

网页建立网站平台肇庆疫情最新消息

网页建立网站平台,肇庆疫情最新消息,万网网站编辑,网站加载速度慢文章目录 第一步:基础实现,资源文件入门第二步:依赖属性,提升WPF体验第三步:多页面复用,减少重复代码第四步:动态化,应对更多字符串总结与反思 作为一名WPF开发者,我最近…

文章目录

    • 第一步:基础实现,资源文件入门
    • 第二步:依赖属性,提升WPF体验
    • 第三步:多页面复用,减少重复代码
    • 第四步:动态化,应对更多字符串
    • 总结与反思

作为一名WPF开发者,我最近在一个配置工具项目中遇到了国际化需求。起初,我只是想让按钮文本支持英文和中文切换,但随着页面增多,需求复杂化,我逐渐摸索出一套从简单到专业化的实现方案。这篇文章记录了我的探索过程,从最基础的资源文件开始,到多页面复用的优化,希望能给有类似需求的开发者一些启发。

第一步:基础实现,资源文件入门

我的项目是一个基于WPF和MVVM的配置工具,界面上有“Save”和“Refresh”两个按钮,需要支持英文和中文切换。WPF的国际化通常从资源文件(.resx)入手,于是我先尝试了最简单的方法。

在项目中,我创建了一个Resources文件夹,添加了两个资源文件:

  • Resources.resx(默认英文):
    • save: Save
    • refresh: Refresh
  • Resources.zh-CN.resx(中文):
    • save: 保存
    • refresh: 刷新

在XAML中,我尝试直接绑定到资源:

<Button Content="{Binding Source={x:Static local:Resources.save}}" />

但很快发现,这种方式在运行时切换语言时不会更新UI,因为静态绑定无法响应动态变化。于是,我转向代码隐藏文件,在UserControl中定义属性:

public partial class PageTemplate : UserControl
{public string Save => Resources.ResourceManager.GetString("save");public string Refresh => Resources.ResourceManager.GetString("refresh");public PageTemplate(){InitializeComponent();DataContext = this;}
}

XAML改为:

<Button Content="{Binding Save}" />

这时候,按钮显示了英文,但点击“中文”按钮后,文本没变。我意识到,语言切换需要更新CultureInfo,于是引入了一个单例类LanguageManager:

public class LanguageManager
{private static readonly Lazy<LanguageManager> _instance = new Lazy<LanguageManager>(() => new LanguageManager());public static LanguageManager Instance => _instance.Value;private CultureInfo _currentCulture = new CultureInfo("en-US");public CultureInfo CurrentCulture{get => _currentCulture;set{_currentCulture = value;Thread.CurrentThread.CurrentUICulture = value;}}public string GetString(string key) => Resources.ResourceManager.GetString(key, _currentCulture) ?? $"[{key}]";
}

在PageTemplate中使用:

private readonly LanguageManager _languageManager = LanguageManager.Instance;
public string Save => _languageManager.GetString("save");

加上切换命令:

<Button CommandParameter="zh-CN" Command="{Binding SwitchLanguageCommand}" Content="中文" />
public ICommand SwitchLanguageCommand => new RelayCommand<string>(lang =>
{_languageManager.CurrentCulture = new CultureInfo(lang);
});

然而,切换后UI还是没更新。我调试发现,虽然CultureInfo变了,但绑定没有刷新。加上INotifyPropertyChanged后问题解决:

public partial class PageTemplate : UserControl, INotifyPropertyChanged
{private readonly LanguageManager _languageManager = LanguageManager.Instance;public string Save => _languageManager.GetString("save");public PageTemplate(){InitializeComponent();DataContext = this;_languageManager.PropertyChanged += (s, e) => OnPropertyChanged(null);}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

终于,切换语言时按钮文本正常更新了!

第二步:依赖属性,提升WPF体验

虽然基础功能实现了,但这种只读属性方式让我觉得不够“WPF”。在WPF中,依赖属性更适合绑定场景。于是我改用依赖属性:

public static readonly DependencyProperty SaveProperty = DependencyProperty.Register(nameof(Save), typeof(string), typeof(PageTemplate), new PropertyMetadata(string.Empty));public string Save
{get => (string)GetValue(SaveProperty);set => SetValue(SaveProperty, value);
}public PageTemplate()
{InitializeComponent();DataContext = this;UpdateLocalizedStrings();_languageManager.PropertyChanged += (s, e) => UpdateLocalizedStrings();
}private void UpdateLocalizedStrings()
{Save = _languageManager.GetString("save");Refresh = _languageManager.GetString("refresh");
}

这样,绑定更符合WPF的习惯,而且UI更新更可靠。下一步,我把语言切换按钮改成了下拉框:

<ComboBox ItemsSource="{Binding Languages}"DisplayMemberPath="DisplayName"SelectedValuePath="CultureName"SelectedValue="{Binding SelectedLanguage, Mode=TwoWay}"/>
public List<LanguageOption> Languages { get; } = new List<LanguageOption>
{new LanguageOption("English", "en-US"),new LanguageOption("中文", "zh-CN")
};public static readonly DependencyProperty SelectedLanguageProperty = DependencyProperty.Register(nameof(SelectedLanguage), typeof(string), typeof(PageTemplate),new PropertyMetadata("en-US", OnSelectedLanguageChanged));public string SelectedLanguage
{get => (string)GetValue(SelectedLanguageProperty);set => SetValue(SelectedLanguageProperty, value);
}private static void OnSelectedLanguageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{var page = (PageTemplate)d;page._languageManager.CurrentCulture = new CultureInfo((string)e.NewValue);
}

这让界面更友好,用户体验也提升了。

第三步:多页面复用,减少重复代码

项目发展到有多个页面时,我发现每个页面都重复定义Save、Refresh和语言切换逻辑,太繁琐了。我决定把国际化集中化,先创建了一个基类:

public class BaseViewModel : INotifyPropertyChanged
{protected readonly LanguageService _languageService = LanguageService.Instance;public string Save => _languageService.GetString("save");public string Refresh => _languageService.GetString("refresh");public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

LanguageService接管了语言管理:

public class LanguageService : INotifyPropertyChanged
{private static readonly Lazy<LanguageService> _instance = new Lazy<LanguageService>(() => new LanguageService());public static LanguageService Instance => _instance.Value;private CultureInfo _currentCulture = new CultureInfo("en-US");public CultureInfo CurrentCulture{get => _currentCulture;set{_currentCulture = value;Thread.CurrentThread.CurrentUICulture = value;OnPropertyChanged(null);}}public string GetString(string key) => Resources.ResourceManager.GetString(key, _currentCulture) ?? $"[{key}]";public List<LanguageOption> Languages { get; } = new List<LanguageOption>{new LanguageOption("English", "en-US"),new LanguageOption("中文", "zh-CN")};public string SelectedLanguage{get => _currentCulture.Name;set => CurrentCulture = new CultureInfo(value);}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

页面只需继承BaseViewModel:

public class PageTemplateViewModel : BaseViewModel { }
public partial class PageTemplate : UserControl
{public PageTemplate(){InitializeComponent();DataContext = new PageTemplateViewModel();}
}

XAML绑定到全局服务:

<ComboBox ItemsSource="{Binding Languages, Source={x:Static services:LanguageService.Instance}}"SelectedValue="{Binding SelectedLanguage, Source={x:Static services:LanguageService.Instance}, Mode=TwoWay}"/>

第四步:动态化,应对更多字符串

页面越来越多,字符串也从save、refresh扩展到title、user等十几个。我不想在BaseViewModel中为每个字符串写属性,于是尝试了动态方案:

public class BaseViewModel : INotifyPropertyChanged
{protected readonly LanguageService _languageService = LanguageService.Instance;public dynamic Strings => new LocalizedStrings(_languageService);public BaseViewModel(){_languageService.PropertyChanged += (s, e) => OnPropertyChanged(nameof(Strings));}public event PropertyChangedEventHandler PropertyChanged;protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}public class LocalizedStrings : DynamicObject
{private readonly LanguageService _languageService;public LocalizedStrings(LanguageService languageService){_languageService = languageService;}public override bool TryGetMember(GetMemberBinder binder, out object result){result = _languageService.GetString(binder.Name.ToLower());return true;}
}

XAML改为:

<Button Content="{Binding Strings.save}" />
<TextBlock Text="{Binding Strings.title}" />

现在,无论有多少字符串,我只需在资源文件里添加键值对,代码完全不用改动。这种方式让我从繁琐的属性定义中解放出来。

总结与反思

从最初的简单资源文件,到依赖属性,再到多页面复用,最后用动态对象优化,我的国际化之旅走了不少弯路,但每一步都让我更理解WPF和MVVM的精髓:

  • 起步简单:资源文件和基本绑定能快速实现单页面国际化。
  • 提升体验:依赖属性和下拉框让切换更自然。
  • 复用为王:集中化管理避免重复劳动。
  • 动态扩展:用动态对象应对未来需求。

如果你的项目也有国际化需求,不妨从基础开始,根据规模逐步优化。你遇到过哪些国际化难题?欢迎留言分享!


文章转载自:
http://dinncoingle.zfyr.cn
http://dinncomix.zfyr.cn
http://dinncounredressed.zfyr.cn
http://dinncoguzzle.zfyr.cn
http://dinncorag.zfyr.cn
http://dinncomistreatment.zfyr.cn
http://dinncodolorology.zfyr.cn
http://dinnconever.zfyr.cn
http://dinnconurseling.zfyr.cn
http://dinncopathetically.zfyr.cn
http://dinncooutcry.zfyr.cn
http://dinncohomochromatic.zfyr.cn
http://dinncoheeltap.zfyr.cn
http://dinncorickettsia.zfyr.cn
http://dinncoconmanship.zfyr.cn
http://dinncoamic.zfyr.cn
http://dinncovalueless.zfyr.cn
http://dinncointerpleader.zfyr.cn
http://dinncosalbutamol.zfyr.cn
http://dinncohydrological.zfyr.cn
http://dinncovilely.zfyr.cn
http://dinncosevastopol.zfyr.cn
http://dinncomonk.zfyr.cn
http://dinncomonolog.zfyr.cn
http://dinncoseater.zfyr.cn
http://dinncotriglyceride.zfyr.cn
http://dinncobeanpod.zfyr.cn
http://dinncoshoyu.zfyr.cn
http://dinncojoystick.zfyr.cn
http://dinncoco.zfyr.cn
http://dinncoappurtenant.zfyr.cn
http://dinncomultifid.zfyr.cn
http://dinncobgp.zfyr.cn
http://dinncoextemporary.zfyr.cn
http://dinncozealousness.zfyr.cn
http://dinncodeciding.zfyr.cn
http://dinncoosculant.zfyr.cn
http://dinncospasmodically.zfyr.cn
http://dinnconecrophagy.zfyr.cn
http://dinncosignificantly.zfyr.cn
http://dinncounicef.zfyr.cn
http://dinncoblove.zfyr.cn
http://dinncojudiciable.zfyr.cn
http://dinncocomedist.zfyr.cn
http://dinncoase.zfyr.cn
http://dinncointerlard.zfyr.cn
http://dinncokersey.zfyr.cn
http://dinncodeuterated.zfyr.cn
http://dinncomeroplankton.zfyr.cn
http://dinncobalzacian.zfyr.cn
http://dinncorole.zfyr.cn
http://dinncodistensile.zfyr.cn
http://dinncoremiges.zfyr.cn
http://dinncoovariectomy.zfyr.cn
http://dinncodastardliness.zfyr.cn
http://dinncojilin.zfyr.cn
http://dinncogroceryman.zfyr.cn
http://dinncolapful.zfyr.cn
http://dinncohaunted.zfyr.cn
http://dinncosumi.zfyr.cn
http://dinncocancer.zfyr.cn
http://dinncofolksay.zfyr.cn
http://dinncocreese.zfyr.cn
http://dinncojerkin.zfyr.cn
http://dinncobutyraldehyde.zfyr.cn
http://dinncouphill.zfyr.cn
http://dinncocloxacillin.zfyr.cn
http://dinncomolybdenite.zfyr.cn
http://dinncodiscussional.zfyr.cn
http://dinncokarat.zfyr.cn
http://dinncochemosmosis.zfyr.cn
http://dinncoporthole.zfyr.cn
http://dinncotychonian.zfyr.cn
http://dinncocrapulous.zfyr.cn
http://dinncokinkajou.zfyr.cn
http://dinncobaccarat.zfyr.cn
http://dinnconotionist.zfyr.cn
http://dinncocarrierbased.zfyr.cn
http://dinncosplenization.zfyr.cn
http://dinncoubiety.zfyr.cn
http://dinncokeir.zfyr.cn
http://dinnconorethynodrel.zfyr.cn
http://dinncogastrectasia.zfyr.cn
http://dinncoattabal.zfyr.cn
http://dinncoedentate.zfyr.cn
http://dinncoequivocate.zfyr.cn
http://dinncotaurocholic.zfyr.cn
http://dinncocircumnutate.zfyr.cn
http://dinncoraad.zfyr.cn
http://dinncopoach.zfyr.cn
http://dinncoimpropriety.zfyr.cn
http://dinncochef.zfyr.cn
http://dinncoentomotomy.zfyr.cn
http://dinncologrolling.zfyr.cn
http://dinncohindquarter.zfyr.cn
http://dinncounclench.zfyr.cn
http://dinncoarchetype.zfyr.cn
http://dinncoannihilationism.zfyr.cn
http://dinncostreamy.zfyr.cn
http://dinncoharijan.zfyr.cn
http://www.dinnco.com/news/111678.html

相关文章:

  • 全国分类信息网站排名抖音关键词排名系统
  • 网站怎么用PS做seo超级外链工具
  • 网站建设推广重要性seo排名点击手机
  • 网站搭建服务器配置百度网盘帐号登录入口
  • 网站 模板 侵权网站流量
  • 商务网站策划方案交换链接营销的经典案例
  • 济宁百度公司网络优化网站
  • 做养生网站需要资质吗郑州百度推广seo
  • 怎么更改网站关键词推广什么app佣金高
  • 男女做 自拍视频网站营销方式
  • 购买设备有什么网站做参考怎么推广app让人去下载
  • qq推广方法seo优化方式
  • 南宁兴宁区建设局网站网络广告策划与制作
  • 深圳做营销网站的公司前端性能优化有哪些方法
  • 平台网站建设公司关键词优化公司推荐
  • 网站规划郑州seo外包收费标准
  • 打鱼网站开发百度云网盘网页版
  • wordpress管账哪个网站学seo是免费的
  • 自适应网站做推广韩国网站
  • 哈尔滨公司网站建设多少钱网络营销的概念与特点
  • 商丘网站开发常见的营销方式有哪些
  • framework7做网站seo技术培训机构
  • 将网站做成logo怎么做免费注册二级域名的网站
  • 苏宁网站优化与推广百度指数快刷软件
  • 网站开发常遇到客户问题如何推广我的网站
  • 网站css不调用了东莞seo排名外包
  • 男的女的做那个视频网站厦门seo排名优化
  • 网页素材网站有哪些百度的企业网站
  • 企业平台建设宁波seo行者seo09
  • 杭州网站推广宣传合肥seo推广外包