【问题标题】:WPF XAML ListBox bind to arrayWPF XAML ListBox 绑定到数组
【发布时间】:2015-09-15 17:11:47
【问题描述】:

所以我有一个浮点数组,我想将它作为 ListBox 中的 ItemSource。
在 ItemTemplate 里面我有一个进度条,它应该将它的 Progress 值绑定到给定的浮点值。但是我永远看不到这些值实际上绑定到 Progress 属性。

xaml 代码(我不知道我是否错了,但我预计会有从 float 到 double 的隐式转换):

<ListBox ItemsSource="{Binding CoreLoads, Mode=OneWay}" BorderThickness="0">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate DataType="{x:Type sys:Double}">
            <StackPanel>
                <ctrl:MetroProgressBar Orientation="Vertical" Progress="{Binding}" ExtenedBorderWidth="0.2" Width="30" Height="50" VerticalAlignment="Center"
                                       HorizontalAlignment="Center" BorderBrush="Black" BorderThickness="2" Background="White" Margin="5"/>
                <TextBlock Margin="0,3,0,3" HorizontalAlignment="Center" Text="{Binding LastUpdateTime, StringFormat='{}{0:hh:mm:ss tt}', Mode=OneWay}"
                           DataContext="{Binding DataContext, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

xmlns:sys="clr-namespace:System;assembly=mscorlib"

以及房产本身:

public double[] CoreLoads
{
    get { return cpuManagement.ProcessorInfo.LoadPercentages; }
}

注意:我使用的进度条是自定义控件,继承自System.Windows.Controls.Control

问题似乎是数组的值没问题,但是当绑定到 TextBlock 时,值是 0,所以进度条的进度总是 0。所以,我是否有正确的数据模板双数组?还是我应该换成另一种类型的收藏?

【问题讨论】:

  • 尝试将数据绑定到ProgressBar.Value Property
  • @Sheridan 我应该提到我正在使用的进度条是一个继承System.Windows.Constrols.Constrol 的自定义控件。所以没有价值属性(在这种情况下可以说ProgressBar.Value = MetroProgressBar.Progress。)
  • 那么,您想将进度条的值绑定到您的 ListBox 的选定值吗?
  • @floyd 是的,这正是我想要做的。但我不知道我的方法是否正确,因为您通常会为模板提供数据类型并绑定到其成员(?)(我对 wpf 很陌生)。

标签: arrays wpf xaml data-binding listbox


【解决方案1】:

我猜你应该在 ViewModel 中创建一个属性(假设你使用的是 MVVM 模式),它将代表 ListBox 的选定值:

    private double selectedCoreLoad;
    public Double SelectedCoreLoad
    {
        get
        {
            return selectedCoreLoad;
        }
        set
        {
            if (selectedCoreLoad != value)
            {
                selectedCoreLoad = value;
                RaisePropertyChanged("SelectedCoreLoad");
            }
        }
    }

然后,您应该将 ListBox 的选定值绑定到此属性:

<ListBox ItemsSource="{Binding CoreLoads, Mode=OneWay}" SelectedValue="{Binding SelectedCoreLoad, Mode=TwoWay}" BorderThickness="0">

<ctrl:MetroProgressBar Orientation="Vertical" Progress="{Binding SelectedCoreLoad}" ExtenedBorderWidth="0.2" Width="30" Height="50" VerticalAlignment="Center"
                                       HorizontalAlignment="Center" BorderBrush="Black" BorderThickness="2" Background="White" Margin="5"/>

UPD

改用 ObservableCollection:

private ObservableCollection<Double> coreLoads;
public ObservableCollection<Double> CoreLoads
{
    get { return coreLoads; }
    set
    {
        coreLoads = value;
        RaisePropertyChanged("CoreLoads");
    }
}

【讨论】:

  • 首先感谢您指出我的代码中的错字。第二次尝试了这个,我发现 xaml 实际上是在使用 System.Single 而不是 double/float 值。编写转换器后,我会检查它是否可以工作。
  • 现在经过测试它仍然没有显示任何内容。也许我会通过代码尝试它,即使这不是使用 MVVM 的解决方案。
  • 你确定你已经在你的 ViewModel 的基类中实现了 INotifyPropertyChanged 接口吗?当您在 ListBox 中选择新值时,我还会尝试检查 SelectedCoreLoad 属性是否发生变化。
  • INotifyPropertyChanged 在我的视图模型的基类中实现。但实际上 SelectedCoreValue 的值永远不会使用SelectedValue 访问。对于SelectedItem,有读写尝试(总是值为0)。但是我发现了问题:数组中返回的值是可以的,但是当将它们绑定到 TextBlock 时,它们总是 0 而不是例如6.545、4.234、0、65.123。
【解决方案2】:

所以找到了答案:ListBox 似乎不像ItemsSource 那样喜欢数组。将源更改为双重列表后,一切正常。

public List<double> CoreLoads
{
    get { return new List<double>(cpuManagement.ProcessorInfo.LoadPercentages); }
}

【讨论】:

    猜你喜欢
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 2012-06-20
    相关资源
    最近更新 更多