WPF Create a reuseable UserControl that binds to ObservableCollection<float>

39 Views Asked by At

I am trying to creare a reusable UserControl that can edit an ObservableCollection this what i got: enter image description here

The problem is the values insdie the array wont update from the UI, or from the property (code).

i got the textboxes to shows, but changing value from UI wont update the property collection.

i want to avoid wrapping the floats with a class.

this is what i got : UserControl.xaml:

 <Border BorderThickness="1" BorderBrush="Silver" DataContext="{Binding ElementName=textboxesUserControl}">
     <StackPanel>

         <WrapPanel>
             <Label Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:NumberOfTextBoxs}}, Path=MainLabel}" VerticalAlignment="Center" />
             <Button Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:NumberOfTextBoxs}}, Path=ShowAllButton,Converter={StaticResource BooleanToVisibilityConverter}}" 
             Content="All"
             HorizontalAlignment="Center" HorizontalContentAlignment="Stretch"
             VerticalContentAlignment="Stretch" VerticalAlignment="Center"  Click="Button_Click"/>
         </WrapPanel>
         <ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel" CanContentScroll="True" PanningMode="HorizontalOnly" Background="Transparent" >

             <WrapPanel >



                 <ItemsControl x:Name="items"  AlternationCount="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:NumberOfTextBoxs}},Path=NumberOfTextBoxes}">
                     <ItemsControl.ItemsSource>
                         <MultiBinding Converter="{StaticResource LimitListToCountConvertor}" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
                             <Binding RelativeSource="{RelativeSource AncestorType={x:Type local:NumberOfTextBoxs}}" Path="Values" />
                             <Binding RelativeSource="{RelativeSource AncestorType={x:Type local:NumberOfTextBoxs}}" Path="NumberOfTextBoxes" />
                             
                         </MultiBinding>
                     </ItemsControl.ItemsSource>
                     <ItemsControl.Resources>
                         <domain:BindingProxy x:Key="proxy" Data="{Binding }" />
                     </ItemsControl.Resources>
                     <ItemsControl.ItemTemplate>
                         <DataTemplate>
                             <Border Margin="1" BorderBrush="Silver" BorderThickness="1" >
                                 <TextBox  md:ValidationAssist.UsePopup="True"  md:HintAssist.Hint="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Mode=TemplatedParent}, StringFormat={}{0}:,Converter={StaticResource math},ConverterParameter=x+1}" MaxWidth="80"  Style="{StaticResource MaterialDesignFloatingHintTextBox}"  VerticalAlignment="Center" HorizontalAlignment="Center">
                                     <TextBox.Text>
                                             <Binding  Path="." UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True" Mode="TwoWay">
                                                 <Binding.ValidationRules>
                                                     <domain:RangeValidtaions  ValidatesOnTargetUpdated="True">
                                                         <domain:RangeValidtaions.WrapperMinMax>
                                                             <domain:Wrapper Min="{Binding Source={StaticResource proxy}, Path=Data.Min,UpdateSourceTrigger=PropertyChanged}"
                                                                                   Max="{Binding Source={StaticResource proxy}, Path=Data.Max,UpdateSourceTrigger=PropertyChanged}" />
                                                         </domain:RangeValidtaions.WrapperMinMax>
                                                     </domain:RangeValidtaions>
                                                 </Binding.ValidationRules>
                                             </Binding>
                                         </TextBox.Text>
                                     </TextBox>
                                
                             </Border>
                         </DataTemplate>
                     </ItemsControl.ItemTemplate>
                     <ItemsControl.ItemsPanel>
                         <ItemsPanelTemplate>
                             <WrapPanel Orientation="Horizontal" IsItemsHost="true"/>
                         </ItemsPanelTemplate>
                     </ItemsControl.ItemsPanel>

                 </ItemsControl>
             </WrapPanel>
         </ScrollViewer>
     </StackPanel>
 </Border>

UserControl.xaml.cs:

  public static readonly DependencyProperty NumOfTextBoxes = DependencyProperty.Register(name: nameof(NumberOfTextBoxes), propertyType: typeof(int), ownerType: typeof(NumberOfTextBoxs), typeMetadata: new FrameworkPropertyMetadata(defaultValue: 1,changed));
  public static readonly DependencyProperty MinDp = DependencyProperty.Register(name: nameof(Min), propertyType: typeof(float), ownerType: typeof(NumberOfTextBoxs), typeMetadata: new FrameworkPropertyMetadata(defaultValue: 0f));
  public static readonly DependencyProperty MaxDp = DependencyProperty.Register(name: nameof(Max), propertyType: typeof(float), ownerType: typeof(NumberOfTextBoxs), typeMetadata: new FrameworkPropertyMetadata(defaultValue: 1f));
  public static readonly DependencyProperty ShowAllButtonDp = DependencyProperty.Register(name: nameof(ShowAllButton), propertyType: typeof(bool), ownerType: typeof(NumberOfTextBoxs), typeMetadata: new FrameworkPropertyMetadata(defaultValue: true));
  public static readonly DependencyProperty MainLabelDp = DependencyProperty.Register(name: nameof(MainLabel), propertyType: typeof(string), ownerType: typeof(NumberOfTextBoxs), typeMetadata: new FrameworkPropertyMetadata(defaultValue: ""));
  public static readonly DependencyProperty ValuesDp = DependencyProperty.Register(name: nameof(Values), propertyType: typeof(ObservableCollection<float>), ownerType: typeof(NumberOfTextBoxs), typeMetadata: new FrameworkPropertyMetadata(new ObservableCollection<float>()));

  private static void changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
      
  }

  public static readonly DependencyProperty CommandDp = DependencyProperty.Register(name: nameof(CommandAllButton), propertyType: typeof(ICommand), ownerType: typeof(NumberOfTextBoxs), typeMetadata: new FrameworkPropertyMetadata());
  public static readonly DependencyProperty ValidatorDp = DependencyProperty.Register(name: nameof(VadlitionCmd), propertyType: typeof(ICommand), ownerType: typeof(NumberOfTextBoxs), typeMetadata: new FrameworkPropertyMetadata());



  public int NumberOfTextBoxes
  {
      get => (int)GetValue(NumOfTextBoxes);
      set => SetValue(NumOfTextBoxes, value);
  }
  public float Min
  {
      get => (int)GetValue(MinDp);
      set => SetValue(MinDp, value);
  }
  public float Max
  {
      get => (float)GetValue(MaxDp);
      set => SetValue(MaxDp, value);
  }
  public bool ShowAllButton
  {
      get => (bool)GetValue(ShowAllButtonDp);
      set => SetValue(ShowAllButtonDp, value);
  }
  public string MainLabel
  {
      get => (string)GetValue(MainLabelDp);
      set => SetValue(MainLabelDp, value);
  }
  public ObservableCollection<float> Values
  {
      get => ((ObservableCollection<float>)GetValue(ValuesDp));
      set => SetValue(ValuesDp, value);
  }
  public ICommand CommandAllButton
  {
      get => (ICommand)GetValue(CommandDp);
      set => SetValue(CommandDp, value);
  }
  public ICommand VadlitionCmd
  {
      get => (ICommand)GetValue(ValidatorDp);
      set => SetValue(ValidatorDp, value);
  }

MainWindow.xaml:

<utils:NumberOfTextBoxs Grid.ColumnSpan="2" Grid.Row="1"  NumberOfTextBoxes="{Binding MaxTextBoxes}" Min="0" Max="0.99"  MainLabel="Test:" Values="{Binding GainsValues}"/>

EDIT: I've ended up with creating a middle man in the UserControl.xaml.cs That convret the ObservableCollection to a ObservableCollection>, and vice-versa.

0

There are 0 best solutions below