I have a project in order to create a custom control that binds properties to display the properties of the selected item.
For example, I have two instances of my CustomControl, one for "StudentName" and the other for "Student's BloodGroup." For StudentName, I want to bind it to StudentName, and for the BloodGroup, I want to use .
Q1: Why FloatingLabelComboBox can't to set binding data to codebehind.
Q2: how can i set second ComboBox SelectedItem match with SelectedItem of first ComboBox .
FloatingLabelComboBox :
public class FloatingLabelComboBox : ComboBox
{
static FloatingLabelComboBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(FloatingLabelComboBox), new FrameworkPropertyMetadata(typeof(FloatingLabelComboBox)));
}
public static readonly DependencyProperty LabelTextProperty =
DependencyProperty.Register("LabelText", typeof(string), typeof(FloatingLabelComboBox), new PropertyMetadata("LabelText"));
public string LabelText
{
get { return (string)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
public static readonly DependencyProperty LabelForegroundProperty =
DependencyProperty.Register("LabelForeground", typeof(Brush), typeof(FloatingLabelComboBox), new PropertyMetadata(Brushes.AliceBlue));
public Brush LabelForeground
{
get { return (Brush)GetValue(LabelForegroundProperty); }
set { SetValue(LabelForegroundProperty, value); }
}
public static readonly DependencyProperty LabelFontSizeProperty =
DependencyProperty.Register("LabelFontSize", typeof(double), typeof(FloatingLabelComboBox), new PropertyMetadata(10.0));
public double LabelFontSize
{
get { return (double)GetValue(LabelFontSizeProperty); }
set { SetValue(LabelFontSizeProperty, value); }
}
}
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:materialdesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:FloatingLabelComboBox"
xmlns:custom="clr-namespace:FloatingLabelComboBox.CustomControls">
<Style TargetType="{x:Type custom:FloatingLabelComboBox }">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type custom:FloatingLabelComboBox }">
<StackPanel FlowDirection="LeftToRight">
<TextBlock Text="{TemplateBinding LabelText}"
Foreground="{TemplateBinding LabelForeground}"
FontSize="{TemplateBinding LabelFontSize}"
VerticalAlignment="Stretch"
Margin="-5 0 0 0" />
<ComboBox x:Name="textBox"
ItemsSource="{TemplateBinding ItemsSource}"
SelectedItem="{TemplateBinding SelectedItem}"
DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
materialdesign:HintAssist.IsFloating="False"
materialdesign:ColorZoneAssist.Mode="Dark"
materialdesign:HintAssist.HintOpacity="0.10"
materialdesign:HintAssist.FontFamily="Century Gothic"
Foreground="{TemplateBinding Foreground}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
StudentModel :
public class StudentModel : INotifyPropertyChanged
{
private int _studentId;
public int StudentId
{
get => _studentId;
set
{
if (value == _studentId) return;
_studentId = value;
OnPropertyChanged(nameof(_studentId));
}
}
private string _studentName;
public string StudentName
{
get => _studentName;
set
{
_studentName = value;
OnPropertyChanged();
}
}
private ObservableCollection<string> _bloodgroup;
public ObservableCollection<string> BloodGroup
{
get => _bloodgroup;
set
{
_bloodgroup = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Grid>
<StackPanel Margin="30" Orientation="Horizontal" Height="80">
<custom:FloatingLabelComboBox Width="160"
LabelText="Student"
Foreground="AliceBlue"
LabelForeground="LimeGreen"
materialdesign:HintAssist.Hint="Student"
FontSize="20"
LabelFontSize="13"
ItemsSource="{Binding Students}"
DisplayMemberPath="StudentName" SelectedItem="{Binding SelectedStudent,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
/>
<custom:FloatingLabelComboBox Width="160"
Margin="40 0 0 0"
LabelText="Blood Group"
Foreground="AliceBlue"
LabelForeground="LimeGreen"
materialdesign:HintAssist.Hint="Blood Group"
FontSize="20"
LabelFontSize="13" ItemsSource="{Binding SelectedStudent.BloodGroup}"
SelectedItem="{Binding SelectedBloodGroup,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />
<StackPanel>
<TextBlock Text="Categories" Width="100"/>
<ComboBox ItemsSource="{Binding Students}" Foreground="White" Width="100" Height="50" DisplayMemberPath="StudentName" SelectedItem="{Binding SelectedStudent}" />
</StackPanel>
<StackPanel>
<TextBlock Text="Proucts" Width="100"/>
<ComboBox ItemsSource="{Binding SelectedStudent.BloodGroup}" Width="100" Height="50" Foreground="White" SelectedItem="{Binding SelectedBloodGroup}" />
</StackPanel>
</StackPanel>
</Grid>
ViewModel:
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
this.Students = new ObservableCollection<StudentModel>()
{ new StudentModel(){ StudentName = "Jane", BloodGroup = new ObservableCollection<string>() { "A", "B", "AB", "0" }},
new StudentModel(){ StudentName = "Jone", BloodGroup = new ObservableCollection<string>() { "A", "B", "AB", "0" }},
new StudentModel(){ StudentName = "Tina", BloodGroup = new ObservableCollection<string>() {"A", "B", "AB", "0"}}
};
this.SelectedStudent = Students.FirstOrDefault();
}
public ObservableCollection<StudentModel> Students { get; private set; }
public ObservableCollection<string> BloodGroups { get; private set; }
public StudentModel _selectedStudent;
public StudentModel SelectedStudent
{
get { return _selectedStudent; }
set
{
_selectedStudent = value;
if (_selectedStudent != null)
{
BloodGroups = _selectedStudent.BloodGroup;
OnPropertyChanged(nameof(BloodGroups));
}
OnPropertyChanged();
}
}
public string _selectedBloodGroup ;
public string SelectedBloodGroup
{
get { return _selectedBloodGroup; }
set
{
_selectedBloodGroup = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
