Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to achieve it if Key also needs to be dynamic? Key如果也要動態該如何達成 #21

Open
flier268 opened this issue Jun 20, 2024 · 8 comments · May be fixed by #22
Open

How to achieve it if Key also needs to be dynamic? Key如果也要動態該如何達成 #21

flier268 opened this issue Jun 20, 2024 · 8 comments · May be fixed by #22
Labels
enhancement New feature or request epic

Comments

@flier268
Copy link
Contributor

flier268 commented Jun 20, 2024

If I need to create a menu from the database, I need a dynamic language key

public class MenuItem
{
    public string MenuName { get; set; }
}
<TextBlock Text="{Binding MenuName}" />

But, I need MenuName support i18n

@Cricle Cricle added enhancement New feature or request epic labels Jun 20, 2024
@Cricle
Copy link
Owner

Cricle commented Jun 20, 2024

我之前的想法是任意ui框架能绑定任意实现了INotifyPropertyChanged接口的类型

所以可以试试新建类型实现这个接口,属性实现是从数据库获取,实际上我原始设计是假设都是固定key的。

如果有好的想法欢迎PR:)

@flier268
Copy link
Contributor Author

flier268 commented Jun 21, 2024

我弄出來了是弄出來了,不過還要再改一下
為了方便測試,把原本的參數都忽略了,應該要丟給Converter,給他用才對,所以目前只有建構子傳入的參數有作用

<TextBlock Text="{l:DynamicLang {Binding MenuNameKey}}"/>
public class DynamicLang : MarkupExtension
{
    private CompiledBindingExtension CompiledBindingExtension { get; }
    public LanguageManager LangMgr { get; set; }

    public List<object> Args { get; set; } = new List<object>(0);

    public string FixedCulture { get; set; }

    public string DefaultValue { get; set; }

    public bool NoUpdate { get; set; }



    public DynamicLang(CompiledBindingExtension compiledBindingExtension)
    {
        CompiledBindingExtension = compiledBindingExtension;
    }

    public string Key { get; set; }

    private static AoLangConverter _aoLangConverter = new AoLangConverter();
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
         var source = new ObservableSource();
         
        (this.LangMgr ?? LanguageManager.Instance).CultureInfoChanged += (cultureInfo) =>
        {
            source.RaisePropertyChanged();
        };
        var binding = new MultiBinding()
        {
            Bindings = [
                new Binding()
                {
                    Path = CompiledBindingExtension.Path.ToString(),
                    Mode = BindingMode.OneWay,
                },
                new Binding()
                {
                    Path = nameof(ObservableSource.Value),
                    Source = source,
                    Mode = BindingMode.OneWay
                }
            ],
            Converter =_aoLangConverter
        };
        return binding;
    }
}
public class ObservableSource : INotifyPropertyChanged
{
    private bool _value;
    public bool Value
    {
        get => _value;
        set
        {
            _value = value;
            OnPropertyChanged();
        }
    }

    public void RaisePropertyChanged()
    {
        Value = !Value;
    }

    public event PropertyChangedEventHandler? PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class AoLangConverter : IMultiValueConverter
{
    public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
    {

        ILangStrBox langBox = LanguageManager.Instance.CreateLangBox(values[0]!.ToString(), (IList?)(parameter as string)?.Split(','), noUpdate: true);
        return langBox.Value; 
    }
}

這MVVM真難搞,我研究的沒有很深入,MarkupExtension也是這兩天才學怎麼用,這樣是會動,但也許你有更好的方法

@Cricle
Copy link
Owner

Cricle commented Jun 23, 2024

我感觉不用加MarkupExtensions也行,直接是可观察对象里面有2个属性关联,一个控制key一个控制value

这样覆盖了场景,也不至于新增或修改了其他东西

@flier268
Copy link
Contributor Author

我感觉不用加MarkupExtensions也行,直接是可观察对象里面有2个属性关联,一个控制key一个控制value

这样覆盖了场景,也不至于新增或修改了其他东西

這我想過,但這就會要求使用者必須使用那個類別,而不能是string,用MarkupExtension可以大幅減少使用的難度跟要求

@Cricle
Copy link
Owner

Cricle commented Jun 30, 2024

有没有可能在原来的langmarkupextensions基础上修改?

增加一个dynamickey的属性, 因为我想这个设计和框架无关,这样就能在任意ui框架使用了

@flier268
Copy link
Contributor Author

flier268 commented Jun 30, 2024

有没有可能在原来的langmarkupextensions基础上修改?

增加一个dynamickey的属性, 因为我想这个设计和框架无关,这样就能在任意ui框架使用了

對其他框架沒研究,不知道Converter有沒有一樣
如果不考慮這個,應該是可以直接修改的

@Cricle
Copy link
Owner

Cricle commented Jun 30, 2024

如果是只使用了INotifyPropertyChanged接口的话那就是可以适配任意UI了

估计Bind扩展函数需要增加一个DynamicBind的扩展函数才行

@Cricle Cricle linked a pull request Jul 15, 2024 that will close this issue
1 task
@Cricle
Copy link
Owner

Cricle commented Jul 15, 2024

#22 可以看看这个提交 @flier268

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request epic
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants