C# 有一种方法可以将Xamarin.Forms中的滑块分组,以便将值更改为其他值?
我试图将各种滑块元素组合在一起工作。在示例中,如果我有两个元素,它们都设置为50(值从0到100),那么值的总和必须始终为100,因此如果我将其中一个滑块设置为值70,则另一个滑块必须动态减小为30C# 有一种方法可以将Xamarin.Forms中的滑块分组,以便将值更改为其他值?,c#,visual-studio,xaml,xamarin,C#,Visual Studio,Xaml,Xamarin,我试图将各种滑块元素组合在一起工作。在示例中,如果我有两个元素,它们都设置为50(值从0到100),那么值的总和必须始终为100,因此如果我将其中一个滑块设置为值70,则另一个滑块必须动态减小为30 <ListView x:Name="listView" ItemSource="myList"> <ListView.ItemTemplate> <DataTemplate>
<ListView x:Name="listView"
ItemSource="myList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Slider x:Name="slider"
Maximum="100"
Minimum="0"
Value="{Binding MyValue}"
HorizontalOptions="FillAndExpand"
MinimumTrackColor="Black"
MaximumTrackColor="Black"
ThumbColor="{StaticResource myColor}"
ValueChanged="OnValueChanged"
PropertyChanging="ChangingSliderValue"/>
<Label Text="{Binding Source={x:Reference slider}, Path=Value, StringFormat='{0:0}'}"
FontSize="Medium"
FontAttributes="Bold"
HorizontalOptions="End"
WidhtRequest="40"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Xaml页面类的一部分是:
namespace MyApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SliderPage: ContentPage
{
private ObservableCollection<MyClass> list = new ObservableCollection<MyClass>();
...
public SliderPage ()
{
InitializeComponent();
InitList();
listView.ItemsSource = list;
...
}
private void InitList () ...
private void ChangingSliderValue (object sender, PropertyChangedEventArgs e)
{
//Code to stick together the slider...
}
}
名称空间MyApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
公共部分类幻灯片页:ContentPage
{
私有ObservableCollection列表=新ObservableCollection();
...
公共幻灯片页()
{
初始化组件();
InitList();
listView.ItemsSource=列表;
...
}
私有void InitList()。。。
私有void ChangingSliderValue(对象发送方,PropertyChangedEventArgs e)
{
//将滑块粘在一起的代码。。。
}
}
有没有关于如何实现我的目标的建议
工作,但不动态显示
您需要在属性MyValue上实现接口INotifyPropertyChanged,以便元素在运行时更新
顺便说一下,由于您在项目中使用了数据绑定,所以最好在ViewModel中处理逻辑
在圣诞节
视图模型
public class MyViewModel
{
public ObservableCollection<MyClass> MySource { get; set; }
bool isFirstLoad = true;
public MyViewModel()
{
MySource = new ObservableCollection<MyClass>() {
new MyClass(){MyValue = 50,Id=0 },
new MyClass(){MyValue = 50,Id=1 },
};
foreach (MyClass model in MySource)
{
model.PropertyChanged += Model_PropertyChanged;
}
}
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName== "MyValue")
{
//handle your logic here as you need
MyClass model = sender as MyClass;
foreach (MyClass item in MySource)
{
if (model.Id != item.Id)
{
item.MyValue = 100 - model.MyValue;
}
}
}
}
}
使用Slider.ValueChanged事件:嗯,我先使用了Slider.ValueChanged事件,然后使用了Slider.ValueChanged事件,然后更改了Slider.ValueChanged,结果是相同的,不起作用。几分钟前我编写的逻辑起作用,但没有动态显示:在
InitList()中
我添加了行myClass.PropertyChanged+=ChangedValue
(要知道我在更改哪个对象的值)。然后在滑块中。更改值
我编写了逻辑以减少其他对象的值,但它不会显示,但如果我更改页面,滑块位置会根据值而更改。我需要在更改时显示它,而不是刷新页面。它现在工作了吗?@LucasZhang MSFT我正在尝试,我正在调整代码,谢谢你非常感谢你的帮助。你的例子正是我想要的。如果对你有帮助,别忘了接受它:)
<ListView
ItemsSource="{Binding MySource}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" HeightRequest="300" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Slider x:Name="slider"
Maximum="100"
Minimum="0"
Value="{Binding MyValue,Mode=TwoWay}"
HorizontalOptions="FillAndExpand"
MinimumTrackColor="Black"
MaximumTrackColor="Black"/>
<Label Text="{Binding Source={x:Reference slider}, Path=Value, StringFormat='{0:0}'}"
FontSize="20"
FontAttributes="Bold"
WidthRequest="40"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
public class MyClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public int Id { get; set; } // add this property to index the slider
private int _value;
private string _name;
private bool _someBool;
public int MyValue {
get
{
return _value;
}
set
{
if(_value!=value)
{
_value = value;
OnPropertyChanged("MyValue");
}
}
}
public string Name { get { return _name; } set { _name = value; } }
public bool SomeBool { get { return _someBool; } set { _someBool = value; OnPropertyChanged("SomeBool"); } }
void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class MyViewModel
{
public ObservableCollection<MyClass> MySource { get; set; }
bool isFirstLoad = true;
public MyViewModel()
{
MySource = new ObservableCollection<MyClass>() {
new MyClass(){MyValue = 50,Id=0 },
new MyClass(){MyValue = 50,Id=1 },
};
foreach (MyClass model in MySource)
{
model.PropertyChanged += Model_PropertyChanged;
}
}
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName== "MyValue")
{
//handle your logic here as you need
MyClass model = sender as MyClass;
foreach (MyClass item in MySource)
{
if (model.Id != item.Id)
{
item.MyValue = 100 - model.MyValue;
}
}
}
}
}
public xxxPage()
{
InitializeComponent();
BindingContext = new MyViewModel();
}