我最难找到一种方法来解决我在滑块和文本框上的数据绑定问题。
设置:滑块的当前值显示在文本框内。当用户拖动滑块时,值会反映在文本框中。用户可以选择拖动滑块并释放到他选择的值,单击滑块轨道上的任意位置设置值或在texbox中手动输入值。在最后一种情况下,在文本框中输入的值应该更新滑块位置。
texbox 以两种方式绑定到 datacontext 属性,而滑块以一种方式绑定到同一属性。当用户滑动或点击滑块跟踪器时,我使用滑块的dragcompleted事件通知datacontext修改。另一方面,当用户单击跟踪器时,我使用滑块的 OnValueChanged 事件来通知数据上下文(并使用标志来确保 OnValueChanged 不是由滑块移动触发的)
问题: OnValueChanged 事件即使在使用绑定值初始化滑块值时也会触发,因此我无法确定该值实际上是来自用户还是来自绑定。
您能否建议进行绑定的替代方法,以确保我们可以区分滑块的用户更新和绑定更新?谢谢你!
更新对不起,我忘了提及为什么我没有直接绑定滑块和文本框两种方式,如下面的答案所建议的。对数据上下文值的更新应该触发对后端服务器的调用并从数据库中检索数据。问题是当用户拖动滑块时,它会不断触发更新。我只依靠实际的 onValueChanged 事件来调用 DoWhatever 方法来解决这个问题。我希望这更清楚一点。很抱歉省略了这个...
我快速整理了下面的示例供您尝试。
xml:
<Window x:Class="SliderIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Slider Name="slider" VerticalAlignment="Top"
ValueChanged="slider_ValueChanged"
Thumb.DragStarted="slider_DragStarted"
Thumb.DragCompleted="slider_DragCompleted"
Value="{Binding Count}"
Width="200"
Minimum="0"
Maximum="100"/>
<TextBox VerticalAlignment="Top"
HorizontalAlignment="Left"
Grid.Column="1"
Width="100"
Text="{Binding Count,Mode=TwoWay,UpdateSourceTrigger=LostFocus}"
Height="25"/>
</Grid>
后面的代码:
using System.Windows;
namespace SliderIssue
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private bool _dragStarted;
public MainWindow()
{
InitializeComponent();
var item = new Item();
DataContext = item;
}
private void slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (!_dragStarted)
{
var item = (Item)DataContext;
item.DoWhatever(e.NewValue);
}
}
private void slider_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
{
_dragStarted = true;
}
private void slider_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
{
_dragStarted = false;
var item = (Item) DataContext;
item.DoWhatever(slider.Value);
}
}
}
一个简单的数据类:
using System.ComponentModel;
namespace SliderIssue
{
public class Item : INotifyPropertyChanged
{
private int _count = 50;
public int Count
{
get { return _count; }
set
{
if (_count != value)
{
_count = value;
DoWhatever(_count);
OnPropertyChanged("Count");
}
}
}
public void DoWhatever(double value)
{
//do something with value
//and blablabla
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}