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(
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
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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(
Hast du denn auch den DataContext
gesetzt (s.a. Verwenden des DataContext)?
Ansonsten schau in die Binding-Warnungen: Diagnose der XAML-Datenbindung
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(