Laden...

Fehlermeldung beim Einbinden eines UserControl

Erstellt von Sindelfinger vor einem Jahr Letzter Beitrag vor einem Jahr 472 Views
S
Sindelfinger Themenstarter:in
39 Beiträge seit 2019
vor einem Jahr
Fehlermeldung beim Einbinden eines UserControl

Hallo liebe Forenmitglieder,

ich habe mir ein kleines UserControl gebaut, welches zwei Labels und einen Slider beinhaltet. Diesem habe ich vier Properties verpasst


    public partial class LabeldSlider : UserControl
    {
        private string textContent;
        private int minVal;
        private int maxval;
        private int setval;

        public string TextContent
        {
            get { return textContent; }
            set { textContent = value; }
        }
        public int MinVal
        {
            get { return minVal; }
            set { minVal = value; }
        }
        public int MaxVal
        {
            get { return maxval; }
            set { maxval = value; }
        }
        public int SetVal
        {
            get { return setval; }
            set { setval = value; }
        }

        public LabeldSlider()
        {
            InitializeComponent();
        }
    }

Die recht überschaubare XAML hierzu (verschönert wird das Ganze noch, wenn es läuft):


<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="5*"/>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>
            <Label Content="{Binding ElementName=TextContent}" Foreground="White"
                   Grid.Column="0"/>
            <Slider x:Name="Slider"  Grid.Column="1"
                    Maximum="{Binding XPath=MaxVal}"
                    Minimum="{Binding XPath=MinVal}"
                    Value="{Binding XPath=SetVal}" SmallChange="1" TickFrequency="0" 
                    LargeChange="0"/>
            <Label x:Name="Werte" Grid.Column="2" 
                   Content="{Binding ElementName=Slider, Path=Value}"
                   Foreground="White"/>
    </Grid>
</UserControl>

Jetzt wollte ich das ganze Ding in eine Page integrieren und stoße jetzt beim Binding auf einen interessanten Fehler: > Fehlermeldung:

Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.int32'

Der Fehler tritt aber nur bei der Parametrierung einer bestimmten Property auf, nämich der "SetVal"


 <theme:LabeldSlider x:Name="CricketScore" 
                TextContent="Cricket StartScore" Grid.Row="1"
                                MaxVal="1000" MinVal="0"
                                SetVal="{Binding CStartScore}">
   
            </theme:LabeldSlider>

Meine Vermutung ist, daß die von mir vergebenen Properties wohl nicht ganz den erforderlichen Vorgaben entsprechen. Könnte da mal jemand drüberschauen?

2 stupid 4 chess? No way.
2 stupid 4 C#? It seems so X(

16.806 Beiträge seit 2008
vor einem Jahr

Der Fehler sollte sich eigentlich sehr gut googlen lassen, da er sehr häufig auftritt - und soweit ich weiß nichts mit einem User Control zutun hat, sondern mit einem PropertyBinding.

Wenn ich das richtig sehe, dann will Dein SetVal ein Integer, Du gibst aber ein Binding.
Das würde auch zur Fehlermeldung passen.

Was Du womöglich willst ist kein Integer Property, sondern ein Dependency Property.
How to implement a dependency property - WPF .NET

S
Sindelfinger Themenstarter:in
39 Beiträge seit 2019
vor einem Jahr

Hey Abt!!

Dir ist hoffentlich schon klar, daß Du NICHT der zweitbeste bist? 😘
Wie immer superschnelle Antwort und die noch mit der Präzision eines Scharfschützen. Ganz herzlichen Dank dafür.

Der Fehler sollte sich eigentlich sehr gut googlen lassen, da er sehr häufig auftritt - und soweit ich weiß nichts mit einem User Control zutun hat, sondern mit einem PropertyBinding.

Gegooglet habe ich natürlich, wurde aber aus den Antworten nicht schlau.

Nachdem ich mich in die Thematik DependencyProperty eingelesen habe, sieht das dann so aus:


public static readonly DependencyProperty SliderValueProperty =
            DependencyProperty.Register("SliderValue", typeof(int),
                typeof(LabeldSlider), new FrameworkPropertyMetadata(default(int),
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public int SliderValue
        {
            get => (int)GetValue(SliderValueProperty);
            set => SetValue(SliderValueProperty, value);
        }

Die Fehlermeldung ist weg, die gewünschte Funktionalität aber noch nicht da. Möchte heißen, daß der Slider weder auf den gewünschten Wert springt, noch daß die Minimum und Maximum - Werte hier wirklich zum tragen kommen. Momentan rührt sich das Ding noch nichtmal 😉. Aber hier bastele ich mal weiter. Da kommt Opi schon noch dahinter.

2 stupid 4 chess? No way.
2 stupid 4 C#? It seems so X(

S
Sindelfinger Themenstarter:in
39 Beiträge seit 2019
vor einem Jahr

Gude TH69,

ich habe den DataContext des Usercontrols auf "Self" gesetzt (darüber bin ich auch schon gestolpert)

Nach einigem hin- und hertesten, lesen, lernen und verstehen, hab ich's jetzt hingekriegt. Dazu ein kleines Testprojekt gebaut. Folgendermaßen sieht das jetzt aus:


<UserControl x:Class="_090_UserControlZeuch.LabeledSlider"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:_090_UserControlZeuch"
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="400"
            DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid HorizontalAlignment="Stretch">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3*"/>
            <ColumnDefinition Width="6*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>

        <Label Content="{Binding SliderLabel}" Foreground="Black"
                   Grid.Column="0" FontSize="25"
               FontWeight="Bold"
               HorizontalAlignment="Left"/>
        <Slider x:Name="sld_Value" Grid.Column="1"
                Minimum="{Binding SliderMinVal}"
                Maximum="{Binding SliderMaxVal}"
                Value="{Binding SliderValue}"
                VerticalAlignment="Center"
                SmallChange="10" LargeChange="100"/>
        <Label x:Name="Werte" Grid.Column="2"
               Foreground="Black" FontSize="25"
               FontWeight="Bold"
               VerticalAlignment="Center"
               HorizontalAlignment="Left"
               Content="{Binding ElementName=sld_Value,Path=Value}"/>
    </Grid>
</UserControl>


Und meine schönen neuen (und endlich auch von mir verstandenen - dankeschön ABT 😘 ) DependencyProperties


using System.Windows;
using System.Windows.Controls;

namespace _090_UserControlZeuch
{
    /// <summary>
    /// Interaktionslogik für LabeledSlider.xaml
    /// </summary>
    public partial class LabeledSlider : UserControl
    {
        public static readonly DependencyProperty SliderValueProperty =
            DependencyProperty.Register("SliderValue", typeof(double),
                typeof(LabeledSlider), new FrameworkPropertyMetadata(default(double),
                    FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public static readonly DependencyProperty SliderLabelProperty =
            DependencyProperty.Register("SliderLabel", typeof(string),
                typeof(LabeledSlider), new FrameworkPropertyMetadata(default(string)));

        public static readonly DependencyProperty SliderMinValProperty =
            DependencyProperty.Register("SliderMinVal", typeof(int),
                typeof(LabeledSlider), new FrameworkPropertyMetadata(default(int)));

        public static readonly DependencyProperty SliderMaxValProperty =
            DependencyProperty.Register("SliderMaxVal", typeof(int),
                typeof(LabeledSlider), new FrameworkPropertyMetadata(default(int)));

        public double SliderValue
        {
            get => (double)GetValue(SliderValueProperty);
            set => SetValue(SliderValueProperty, value);
        }

        public string SliderLabel
        {
            get=> (string)GetValue(SliderLabelProperty);
            set => SetValue(SliderLabelProperty, value);
        }
        
        public int SliderMinVal
        {
            get=> (int)GetValue(SliderMinValProperty);
            set=> SetValue(SliderMinValProperty, value);
        }
        public int SliderMaxVal
        {
            get=> (int)GetValue(SliderMaxValProperty);
            set=> SetValue(SliderMaxValProperty, value);
        }

        
        public LabeledSlider()
        {
            InitializeComponent();
        }
    }
}


Die Implementierung im MainWindow hat eine kleine Unwegbarkeit zutage gefördert.


    <Window.DataContext>
        <local:MainViewModel x:Name="vm"/>
    </Window.DataContext>


            <local:LabeledSlider x:Name="ucSlider" SliderMinVal="{Binding MinVal, ElementName=vm}" 
                                 SliderMaxVal="{Binding MaxVal, ElementName=vm}"
                                 SliderLabel="So heisst die Minna"
                                 SliderValue="{Binding SetVal, ElementName=vm}"/>

Die Bindingengine kam wohl bei den Bindings etwas durcheinander. Danach habe ich testweise mal dir Values mit dem Elementnamen des Viewmodels verknüft und et voilá schon lief die Minna.

Anbei ein Screenshot von meinem kleinen TestWindow.

Danke Jungs! Ihr seid die Größten. Ich wink Euch aus dem Ally Pally zu am Freitag 😉

2 stupid 4 chess? No way.
2 stupid 4 C#? It seems so X(