从文件

时间:2018-02-23 13:53:55

标签: c# xaml uwp win-universal-app

所以我有这个程序,我主要使用x:Bind完成所有绑定,但是我有一个控制页面,我需要生成很多Slider才能操作我存储的数据在ObservableCollection<T>

我真的需要从我的代码中生成那些滑块,因为我需要大约100个它们并且它真的会弄乱我的xmal文件来手工创建它们......

这就是我在代码中创建绑定的方法。当我第一次加载它们时它们也可以工作。但是当我移动滑块时,它们不会改变源数据。

private void CreateGrid()
{
    for (var parameterNumberIndex = 1; parameterNumberIndex < 97; parameterNumberIndex++)
    {
        var paraName = new TextBlock()
        {
            Name = $"Parameter{parameterNumberIndex}",
            FontSize = 25,
            VerticalAlignment = VerticalAlignment.Top,
            Margin = new Thickness(0, 0, 0, 10)
        };

        var slider = new Slider()
        {
            Name = $"ValueSlider{parameterNumberIndex}",
            Width = 200,
            VerticalAlignment = VerticalAlignment.Center,
            HorizontalAlignment = HorizontalAlignment.Center
        };

        var value = new TextBox()
        {
            Name = $"ValueBox{parameterNumberIndex}",
            Margin = new Thickness(10, 5, 0, 0),
            FontSize = 20,
            VerticalAlignment = VerticalAlignment.Top
        };

        var row = new RowDefinition { Height = new GridLength(50, GridUnitType.Pixel) };

        SettingsGrid.RowDefinitions.Add(row);

        var nameBinding = new Binding
        {
            Source = ViewModel.BlockCollection.NamesBlock.Names[parameterNumberIndex].NameString,
            Mode = BindingMode.OneWay
        };

        var valueBinding = new Binding()
        {
            Source = ViewModel.BlockCollection.ParameterBlock.Parameters[parameterNumberIndex].ParameterValue,
            Mode = BindingMode.TwoWay
        };

        var minBinding = new Binding()
        {
            Source = ViewModel.BlockCollection.MinMaxBlock.AllValues[parameterNumberIndex].MinValue,
            Mode = BindingMode.OneWay
        };

        var maxBinding = new Binding()
        {
            Source = ViewModel.BlockCollection.MinMaxBlock.AllValues[parameterNumberIndex].MaxValue,
            Mode = BindingMode.OneWay
        };

        var textBinding = new Binding()
        {
            Path = new PropertyPath("Value"),
            Source = slider,
            Mode = BindingMode.TwoWay
        };

        BindingOperations.SetBinding(paraName, TextBlock.TextProperty, nameBinding);
        BindingOperations.SetBinding(slider, Slider.MinimumProperty, minBinding);
        BindingOperations.SetBinding(slider, Slider.MaximumProperty, maxBinding);
        BindingOperations.SetBinding(slider, Slider.ValueProperty, valueBinding);
        BindingOperations.SetBinding(value, TextBox.TextProperty, textBinding);

        SettingsGrid.Children.Add(paraName);
        SettingsGrid.Children.Add(slider);
        SettingsGrid.Children.Add(value);

        Grid.SetColumn(paraName, 0);
        Grid.SetColumn(slider, 1);
        Grid.SetColumn(value, 2);

        Grid.SetRow(paraName, parameterNumberIndex - 1);
        Grid.SetRow(slider, parameterNumberIndex - 1);
        Grid.SetRow(value, parameterNumberIndex - 1);
    }
}

Source = ...始终为ObservableCollection<T>,具体取决于我需要的类型。

滑块源是uint

的集合

BindableBase是我INotifyPropertyChanged的实现。

public class ParameterBlock : BindableBase
{
    public ParameterBlock()
    {
        this.Parameters = new ObservableRangeCollection<ParameterBlockValue>();
    }

    public ObservableRangeCollection<ParameterBlockValue> Parameters
    {
        get => _parameters;
        set
        {
            _parameters = value;
            OnPropertyChanged();
        }
    }        

    private ObservableRangeCollection<ParameterBlockValue> _parameters;
}

public class ParameterBlockValue : BindableBase
{
    private uint _parameterValue;

    public uint ParameterValue
    {
        get => _parameterValue;
        set
        {
            _parameterValue = value;
            OnPropertyChanged();
        }
    }

    public ParameterBlockValue(uint parameter)
    {
        this.ParameterValue = parameter;
    }

    public override string ToString()
    {
        return $"{this.ParameterValue} {Environment.NewLine}";
    }
}

在我或多或少地完成这个项目并且我不想被困在这里之前,这几乎是我需要解决的最后一步:/

我不知道wpf标签是否错误。但每当我寻找xaml引用时,我偶然发现了wpf的东西,它有点可用。所以,如果它错了,请告诉我,然后将其删除。

要解释一下......在成品中,它将取决于我收到的数据,以决定是否有滑块或文本框。

只是我昨天提出的另一个问题的一个小例子:

enter image description here

1 个答案:

答案 0 :(得分:2)

我看到您在Grid中添加控件,手动生成行。虽然这当然可行,但使用列表控件并在其中创建项目会更好:

<ItemsControl ItemsSource="{x:Bind Data}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <!-- your Sliders, etc. -->
        </DataTemplate>
    </ItemsControl.ItemTemplate>
<ItemsControl>

如果数据可能在多个布局之间有所不同,您可以实现DataTemplateSelector类,覆盖SelectTemplateCore(object item, DependencyObject container)(具体来说,此方法还有另一个具有相同名称但参数数量不同的类别)没有调用)并决定每个项目的正确模板。您可以使用DataTemplates创建多个x:Key作为资源,然后从DataTemplateSelector引用它们。有关示例,请参阅此blog post;有关详情,请参阅documentation