2

我在 MVVM 中的滑块值数据绑定有问题。当价值发生变化时,我的预期价值没有实现。我该如何解决我的问题?
我有一个列表框、一个滑块和一个文本块。列表框绑定到 ListImage,滑块值和文本块文本绑定到 CurrentImage。带有命令的一键导航 lisbox 项目。CurrentImage 是视图模型中的一个属性。当我更改滑块的设置器时,设置器的新值放入滑块设置器的当前值并且列表框的排列被破坏。例如,当我的滑块设置器的值设置为 50 并且我再次将滑块的值更改为 10 时。我的滑块值从 10 导航到 50,而不是更多。它必须导航整个列表框,但不能。有我的代码:

XAML:

<TextBlock Text="{Binding CurrentImage.Index}"/>
<Slider Height="23" HorizontalAlignment="Left" Margin="12,305,0,0" Name="slider1" VerticalAlignment="Top" Width="479" Maximum="{Binding ListImage.Count, Mode=OneTime}"
              Value="{Binding CurrentImage.Index, Mode=TwoWay}"
              SmallChange="1" />
<Button Content="{Binding DisplayPlay}" Command="{Binding PlayCommand}" Height="23" HorizontalAlignment="Left" Margin="507,305,0,0" Name="button1" VerticalAlignment="Top" Width="75" />
<ListBox Height="129" HorizontalAlignment="Left"  Margin="12,334,0,0" ItemsSource="{Binding ListImage}" SelectedItem="{Binding CurrentImage,Mode=TwoWay}" 
                 VerticalAlignment="Top" Width="472">

视图模型:

public class MainViewModel : ViewModelBase
{
    public ICommand PlayCommand { get; set; }
    private DispatcherTimer _Timer;
    public ImageDTO Image { get; set;}
    DataAccess AC = new DataAccess();
    public byte[] Bytes { get; set; }
    public MainViewModel()
    {
        ListImage = AC.OpenImages();
        CurrentImage = ListImage[0];
        Bytes = CurrentImage.Bytes;
        this.PlayCommand = new DelegateCommand(Play, CanPlay);
        DisplayPlay = "Play";
        _Timer = new DispatcherTimer();
        _Timer.Interval = new TimeSpan(0, 0, 0, 0, 2000 / 30);
        _Timer.Tick += new EventHandler(timer_Tick);
    }

    private string _DisplayPlay;
    public string DisplayPlay
    {
        get { return _DisplayPlay; }
        set
        {
            if (_DisplayPlay != value)
            {
                _DisplayPlay = value;
                OnPropertyChanged("DisplayPlay");
            }
        }
    }

    private List<ImageDTO> _ListImage;
    public List<ImageDTO> ListImage
    {
        get { return _ListImage; }
        set
        {
            if (_ListImage != value)
                _ListImage = value;
                OnPropertyChanged("ListImage");
        }
    }

    private ImageDTO _CurrentImage;
    public ImageDTO CurrentImage
    {
        get { return _CurrentImage; }
        set
        {
            if (_CurrentImage != value)
            {
                _CurrentImage = value;
                OnPropertyChanged("CurrentImage");
            }
        }
    }

    public bool CanPlay(object parameter)
    {
        return true;
    }
    public void Play(object parameter)
    {
        if (DisplayPlay == "Play")
        {
            DisplayPlay = "Pause";
            _Timer.Start();
        }
        else
        {
            _Timer.Stop();
            DisplayPlay = "Play";
        }
    }

    private void timer_Tick(object sender, EventArgs e)
    {
        int position = ListImage.FindIndex(x => x.Index == CurrentImage.Index);
        position++;
        if (position == ListImage.Count)
        {
            position = 0;
        }
        else
        {
            CurrentImage = ListImage[position];
        }
    }
4

2 回答 2

5

也许这就是你想要的:

<StackPanel>
    <ListBox x:Name="ImageListBox" IsSynchronizedWithCurrentItem="True">
        <ListBoxItem>Image1</ListBoxItem>
        <ListBoxItem>Image2</ListBoxItem>
        <ListBoxItem>Image3</ListBoxItem>
        <ListBoxItem>Image4</ListBoxItem>
    </ListBox>
    <Slider Value="{Binding ElementName=ImageListBox, Path=SelectedIndex}" 
            Maximum="{Binding ElementName=ImageListBox, Path=Items.Count}"/>
</StackPanel>

您可能希望比本示例更好地处理最大值

于 2013-01-15T14:31:29.533 回答
1

在您的代码中,滑块的值绑定到 CurrentImage 索引,因此当您更改滑块的值时,当前图像的索引将被更改。假设当前图像索引为 5,则滑块的值为 5,那么如果将滑块指针移动到 10 之类的位置,则当前图像索引将设置为 10,这意味着您当前的图像将被修改,所以这意味着它不会导航到列表的第 10 个元素,但它会修改图像的索引(索引为 5)并将其索引设置为 10,换句话说,您将不再拥有索引为 5 和 2 的图像您的图像将具有相同的索引 (10)。

作为一种解决方案,您可以在视图模型中添加另一个属性,如“Index”,并将滑块值绑定到该属性,因此在 get 方法中返回列表中所选项目的索引,并在 set 方法中更改所选项目列表并调用 OnPropertyChanged 并将“Index”作为参数传递。

于 2013-01-15T18:50:28.113 回答