@@ -8,8 +8,7 @@ namespace BootstrapBlazor.Components;
88/// <summary>
99/// 单选框组合组件
1010/// </summary>
11- [ ExcludeFromCodeCoverage ]
12- public partial class RadioListGeneric < TValue >
11+ public partial class RadioListGeneric < TValue > : IModelEqualityComparer < TValue >
1312{
1413 /// <summary>
1514 /// 获得/设置 值为可为空枚举类型时是否自动添加空值 默认 false 自定义空值显示文本请参考 <see cref="NullItemText"/>
@@ -30,56 +29,137 @@ public partial class RadioListGeneric<TValue>
3029 [ Parameter ]
3130 public RenderFragment < SelectedItem < TValue > > ? ItemTemplate { get ; set ; }
3231
33- //private string? GroupName => Id;
34-
35- //private string? ClassString => CssBuilder.Default("radio-list form-control")
36- // .AddClass("no-border", !ShowBorder && ValidCss != "is-invalid")
37- // .AddClass("is-vertical", IsVertical)
38- // .AddClass(CssClass).AddClass(ValidCss)
39- // .Build();
40-
41- //private string? ButtonClassString => CssBuilder.Default("radio-list btn-group")
42- // .AddClass("disabled", IsDisabled)
43- // .AddClass("btn-group-vertical", IsVertical)
44- // .AddClassFromAttributes(AdditionalAttributes)
45- // .Build();
46-
47- //private string? GetButtonItemClassString(SelectedItem item) => CssBuilder.Default("btn")
48- // .AddClass($"active bg-{Color.ToDescriptionString()}", CurrentValueAsString == item.Value)
49- // .Build();
50-
51- ///// <summary>
52- ///// <inheritdoc/>
53- ///// </summary>
54- //protected override void OnParametersSet()
55- //{
56- // var t = NullableUnderlyingType ?? typeof(TValue);
57- // if (t.IsEnum && Items == null)
58- // {
59- // Items = t.ToSelectList<TValue>((NullableUnderlyingType != null && IsAutoAddNullItem) ? new SelectedItem<TValue>(default, NullItemText) : null);
60- // }
61-
62- // base.OnParametersSet();
63- //}
64-
65- ///// <summary>
66- ///// 点击选择框方法
67- ///// </summary>
68- //private async Task OnClick(SelectedItem<TValue> item)
69- //{
70- // if (!IsDisabled)
71- // {
72- // if (OnSelectedChanged != null)
73- // {
74- // await OnSelectedChanged(Items, Value);
75- // }
76- // StateHasChanged();
77- // }
78- //}
79-
80- //private CheckboxState CheckState(SelectedItem<TValue> item) => this.Equals<TValue>(Value, item.Value) ? CheckboxState.Checked : CheckboxState.UnChecked;
81-
82- //private RenderFragment? GetChildContent(SelectedItem<TValue> item) => ItemTemplate == null
83- // ? null
84- // : ItemTemplate(item);
32+ /// <summary>
33+ /// 获得/设置 是否为按钮样式 默认 false
34+ /// </summary>
35+ [ Parameter ]
36+ public bool IsButton { get ; set ; }
37+
38+ /// <summary>
39+ /// 获得/设置 是否显示边框 默认为 true
40+ /// </summary>
41+ [ Parameter ]
42+ public bool ShowBorder { get ; set ; } = true ;
43+
44+ /// <summary>
45+ /// 获得/设置 是否为竖向排列 默认为 false
46+ /// </summary>
47+ [ Parameter ]
48+ public bool IsVertical { get ; set ; }
49+
50+ /// <summary>
51+ /// 获得/设置 按钮颜色 默认为 None 未设置
52+ /// </summary>
53+ [ Parameter ]
54+ public Color Color { get ; set ; }
55+
56+ /// <summary>
57+ /// 获得/设置 数据源
58+ /// </summary>
59+ [ Parameter ]
60+ [ NotNull ]
61+ public IEnumerable < SelectedItem < TValue > > ? Items { get ; set ; }
62+
63+ /// <summary>
64+ /// 获得/设置 SelectedItemChanged 方法
65+ /// </summary>
66+ [ Parameter ]
67+ public Func < TValue , Task > ? OnSelectedChanged { get ; set ; }
68+
69+ /// <summary>
70+ /// 获得/设置 数据主键标识标签 默认为 <see cref="KeyAttribute"/><code><br /></code>用于判断数据主键标签,如果模型未设置主键时可使用 <see cref="ModelEqualityComparer"/> 参数自定义判断 <code><br /></code>数据模型支持联合主键
71+ /// </summary>
72+ [ Parameter ]
73+ [ NotNull ]
74+ public Type ? CustomKeyAttribute { get ; set ; } = typeof ( KeyAttribute ) ;
75+
76+ /// <summary>
77+ /// 获得/设置 比较数据是否相同回调方法 默认为 null
78+ /// <para>提供此回调方法时忽略 <see cref="CustomKeyAttribute"/> 属性</para>
79+ /// </summary>
80+ [ Parameter ]
81+ public Func < TValue , TValue , bool > ? ModelEqualityComparer { get ; set ; }
82+
83+ /// <summary>
84+ /// 获得 当前选项是否被禁用
85+ /// </summary>
86+ /// <param name="item"></param>
87+ /// <returns></returns>
88+ private bool GetDisabledState ( SelectedItem < TValue > item ) => IsDisabled || item . IsDisabled ;
89+
90+ private string ? GroupName => Id ;
91+
92+ private string ? ClassString => CssBuilder . Default ( "radio-list form-control" )
93+ . AddClass ( "no-border" , ! ShowBorder && ValidCss != "is-invalid" )
94+ . AddClass ( "is-vertical" , IsVertical )
95+ . AddClass ( CssClass ) . AddClass ( ValidCss )
96+ . Build ( ) ;
97+
98+ private string ? ButtonClassString => CssBuilder . Default ( "radio-list btn-group" )
99+ . AddClass ( "disabled" , IsDisabled )
100+ . AddClass ( "btn-group-vertical" , IsVertical )
101+ . AddClassFromAttributes ( AdditionalAttributes )
102+ . Build ( ) ;
103+
104+ private string ? GetButtonItemClassString ( SelectedItem < TValue > item ) => CssBuilder . Default ( "btn" )
105+ . AddClass ( $ "active bg-{ Color . ToDescriptionString ( ) } ", Equals ( Value , item . Value ) )
106+ . Build ( ) ;
107+
108+ /// <summary>
109+ /// <inheritdoc/>
110+ /// </summary>
111+ protected override void OnParametersSet ( )
112+ {
113+ base . OnParametersSet ( ) ;
114+
115+ if ( IsButton && Color == Color . None )
116+ {
117+ Color = Color . Primary ;
118+ }
119+
120+ var t = NullableUnderlyingType ?? typeof ( TValue ) ;
121+ if ( t . IsEnum && Items == null )
122+ {
123+ Items = t . ToSelectList < TValue > ( ( NullableUnderlyingType != null && IsAutoAddNullItem ) ? new SelectedItem < TValue > ( default , NullItemText ) : null ) ;
124+ }
125+
126+ Items ??= [ ] ;
127+
128+ // set item active
129+ if ( Value != null )
130+ {
131+ var item = Items . FirstOrDefault ( i => Equals ( Value , i . Value ) ) ;
132+ if ( item == null )
133+ {
134+ Value = default ;
135+ }
136+ }
137+ }
138+
139+ /// <summary>
140+ /// 点击选择框方法
141+ /// </summary>
142+ private async Task OnClick ( SelectedItem < TValue ? > item )
143+ {
144+ if ( ! IsDisabled )
145+ {
146+ CurrentValue = item . Value ;
147+ if ( OnSelectedChanged != null )
148+ {
149+ await OnSelectedChanged ( Value ) ;
150+ }
151+ StateHasChanged ( ) ;
152+ }
153+ }
154+
155+ private CheckboxState CheckState ( SelectedItem < TValue > item ) => this . Equals < TValue > ( Value , item . Value ) ? CheckboxState . Checked : CheckboxState . UnChecked ;
156+
157+ private RenderFragment ? GetChildContent ( SelectedItem < TValue > item ) => ItemTemplate == null
158+ ? null
159+ : ItemTemplate ( item ) ;
160+
161+ /// <summary>
162+ /// <inheritdoc/>
163+ /// </summary>
164+ public bool Equals ( TValue ? x , TValue ? y ) => this . Equals < TValue > ( x , y ) ;
85165}
0 commit comments