Mvvm 处理多个按钮视图

Mvvm 处理多个按钮视图,mvvm,xamarin.forms,Mvvm,Xamarin.forms,我的问题是如何在MVVM中读取按钮单击时控制多个按钮的背景和文本颜色。为了让我的问题更清楚一点,请看一下我附带的UI 我已经在代码背后实现了这一点,即在单击按钮时,我将分别处理所有按钮。原始背景和文本颜色分别为白色和黑色,当您单击除1W以外的任何其他按钮时,该按钮将高亮显示。 在下一个图像中,单击3M 我在每次点击按钮时都这样做了 我知道这种方法不划算,我想学习如何以MVVM的方式实现 编辑: 我创建了一个函数,可以将所有按钮重置为原始UI,并在单击按钮时更改UI void ResetBu

我的问题是如何在MVVM中读取按钮单击时控制多个按钮的背景和文本颜色。为了让我的问题更清楚一点,请看一下我附带的UI

我已经在代码背后实现了这一点,即在单击按钮时,我将分别处理所有按钮。原始背景和文本颜色分别为白色和黑色,当您单击除1W以外的任何其他按钮时,该按钮将高亮显示。 在下一个图像中,单击3M

我在每次点击按钮时都这样做了

我知道这种方法不划算,我想学习如何以MVVM的方式实现

编辑: 我创建了一个函数,可以将所有按钮重置为原始UI,并在单击按钮时更改UI

 void ResetButtonUI()
    {
        lbl1W.BackgroundColor = Color.White;
        lbl1W.TextColor = Color.Black;
        lbl1M.BackgroundColor = Color.White;
        lbl1M.TextColor = Color.Black;
        lbl3M.BackgroundColor = Color.White;
        lbl3M.TextColor = Color.Black;
        lbl6M.BackgroundColor = Color.White;
        lbl6M.TextColor = Color.Black;
        lbl1Y.BackgroundColor = Color.White;
        lbl1Y.TextColor = Color.Black;
    }
每个按钮上都有这样的逻辑

         ResetButtonUI();
         button.BackgroundColor = Color.FromHex(defaultColor);
         button.TextColor = Color.White;

因此有5个选项,用户必须从中选择一个

ViewModel必须包含2个属性:

  • 所有选项的集合
  • 选定选项
应该是这样的

//ReactiveObject来自ReactiveUI=>https://reactiveui.net/
公共类MainViewModel:反应对象
{
私有只读可观察收集选项;
专用TimeSpanItem _选择的选项;
公共ReadOnlyObservableCollection选项{get;}
公共TimeSpanItem SelectedOption{get=>_SelectedOption;set=>this.RaiseAndSetIfChanged(ref _SelectedOption,value);}
公共主视图模型()
{
_选项=新的ObservableCollection();
选项=新的只读可观察集合(_选项);
_添加(新的TimeSpanItem(1,TimeSpanKind.Week));
_添加(新的TimeSpanItem(1,TimeSpanKind.Month));
_添加(新的TimeSpanItem(3,TimeSpanKind.Month));
_添加(新的TimeSpanItem(6,TimeSpanKind.Month));
_添加(新的TimeSpanItem(1,TimeSpanKind.Year));
SelectedOption=_options.Last();
}
}
以及一些数据类型:

public enum TimeSpanKind
{
M=2,
W=1,
Y=3,
周=W,
月=M,
年份=Y,
}
公共类TimeSpanItem
{
公共TimeSpanItem(int值,TimeSpanKind种类)
{
价值=价值;
善良=善良;
}
公共int值{get;}
公共TimeSpanKind种类{get;}
公共重写字符串ToString()
{
返回$“{Value}{Kind}”;
}
}
现在是演讲的时间了。显示可选集合的最简单方法是ListBox或ListView,因为所有内容都可以用XAML连接起来


这就是结果

列表视图
相比,
集合视图
更适合您的需要<代码>列表视图水平放置更复杂

这里是运行GIF。

这是代码

     <CollectionView ItemsSource="{Binding Persons}" HeightRequest="50" SelectionMode="Single" SelectionChanged="CollectionView_SelectionChanged_1" >
            <CollectionView.ItemsLayout>
                <LinearItemsLayout   Orientation="Horizontal" />
            </CollectionView.ItemsLayout>
            <CollectionView.ItemTemplate>
                <DataTemplate>


                    <StackLayout HorizontalOptions="Center"  VerticalOptions="Center" >
                        <Label Text="{Binding FirstName}" FontSize="20"  Margin="20,10,20,0"/>
                    </StackLayout>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
公共列表人员{get;set;}

    public HomepageViewModel() {

        Persons = new List<Person>();
        Persons.Add(new Person() { FirstName = "1W" });
        Persons.Add(new Person() { FirstName = "1M" });
        Persons.Add(new Person() { FirstName = "3M" });
        Persons.Add(new Person() { FirstName = "6M" });
        Persons.Add(new Person() { FirstName = "1Y" });
    }
公共主页视图模型(){
人员=新列表();
添加(newperson(){FirstName=“1W”});
添加(newperson(){FirstName=“1M”});
添加(newperson(){FirstName=“3M”});
添加(newperson(){FirstName=“6M”});
添加(newperson(){FirstName=“1Y”});
}
} 如果您想更改selectItem的颜色,这里有一个相关链接。

你应该学会如何以有效的方式来做,然后你应该知道如何在MVVM中做。试着理解你真正想做的事情。所有这些色彩游戏只是一些逻辑的表现。这种逻辑应该发生在ViewModel中,结果的表示应该留在视图中。查看我的编辑。如果这是一种有效的实现方法,您能给我一些建议吗?尝试使用转换器,并将某种
IsSelected
布尔属性绑定到按钮以处理颜色更改逻辑。我认为每个按钮都应该有一个命令,这样就可以在那里处理新选择的按钮和上一个按钮的
IsSelected
逻辑。尝试使用这种方法来处理所有的点击,最好的方法是使用ListView,我想要的UI将更容易处理。在Xamarin表单中,我必须使用INotifyChanged with listview来更新所选按钮。感谢您的指导。在Xamarin中,您还可以使用ReactiveUI,ReactiveObject已经实现了INotifyPropertyChanged接口。看一看,如果这是最好的方法-我不知道-这取决于你的要求。我认为这将是最好的方法来实施它,为我的项目和其他一切。谢谢你分享你的知识。我会接受你的回答。
   BindingContext = new HomepageViewModel();
    public HomepageViewModel() {

        Persons = new List<Person>();
        Persons.Add(new Person() { FirstName = "1W" });
        Persons.Add(new Person() { FirstName = "1M" });
        Persons.Add(new Person() { FirstName = "3M" });
        Persons.Add(new Person() { FirstName = "6M" });
        Persons.Add(new Person() { FirstName = "1Y" });
    }