How to use UserControls in an ItemsRepeater for UWP - c#

I am trying to use a UserControl inside an ItemsRepeater and having issues with it.I am using Prism and the MVVM model
I defined a UserControl in a separate A.xaml file
<UserControl>
<Grid>
<Button Background="Grey" Content="{x:Bind AViewModel.text}">
<Button>
<Grid>
<UserControl>
The corresponding A.xaml.cs file has the binding to AViewModel which defines the property text
I have another XAML file B.xaml which uses this control defined as follows
<Grid>
<ItemsRepeater ItemSource={"x:Bind BViewModel.ListOfObservableCollection"}>
<ItemRepeater.Layout>
<StackLayout>
</StackLayout>
</ItemRepeater.Layout>
</ItemsRepeater>
</Grid>
This XAML file has a corresponding B.XAML.cs file which binds to BViewModel which has the List of Observable collection. I wish to display a vertical list of button which has text from the List of Observation Collection by using UserControl. How do i achieve this ?

How to use UserControls in an ItemsRepeater for UWP
You could insert UserControl into ItemsRepeater's ItemTemplate. And give UserControl DependencyProperty to receive text value. Please note you need edit ListOfObservableCollection content to AViewModel like the following
UserControl
<UserControl>
<Grid>
<Button Background="Gray" Content="{Binding ButtonContent}" />
</Grid>
</UserControl>
code behind
public sealed partial class AControl : UserControl
{
public AControl()
{
this.InitializeComponent();
(this.Content as FrameworkElement).DataContext = this;
}
public string ButtonContent
{
get { return (string)GetValue(ButtonContentProperty); }
set { SetValue(ButtonContentProperty, value); }
}
// Using a DependencyProperty as the backing store for ButtonContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ButtonContentProperty =
DependencyProperty.Register("ButtonContent", typeof(string), typeof(AControl), new PropertyMetadata(null));
}
Usage
<Page.DataContext>
<local:BViewModel x:Name="ViewModel" />
</Page.DataContext>
<Grid>
<muxc:ItemsRepeater ItemsSource="{Binding ListOfObservableCollection}">
<muxc:ItemsRepeater.ItemTemplate>
<DataTemplate>
<local:AControl ButtonContent="{Binding Text}" />
</DataTemplate>
</muxc:ItemsRepeater.ItemTemplate>
</muxc:ItemsRepeater>
<local:AControl ButtonContent="hh" />
</Grid>
Code behind
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
}
public class AViewModel
{
public string Text { get; set; }
}
public class BViewModel
{
public ObservableCollection<AViewModel> ListOfObservableCollection { get; set; }
public BViewModel()
{
ListOfObservableCollection = new ObservableCollection<AViewModel>();
ListOfObservableCollection.Add(new AViewModel { Text = "Test1" });
ListOfObservableCollection.Add(new AViewModel { Text = "Test1" });
ListOfObservableCollection.Add(new AViewModel { Text = "Test1" });
ListOfObservableCollection.Add(new AViewModel { Text = "Test1" });
}
}

Related

WPF ItemsControl data binding with variable path

I am trying to create a UserControl that contains an ItemsControl which should display Parameters and their values. The values must be editable and these values should be transferred back to the ViewModel.
It should be possible to define which property represents the parameter name and which property the parameter value.
Parameter class:
public class Parameter
{
public string Name { get; set; }
public string Value { get; set; }
}
ViewModel:
public class MyViewModel : INotifyPropertyChanged
{
...
public ObservableCollection<Parameter> Parameters { get; set; }
...
}
UserControl ("ParameterList.xaml"):
<UserControl x:Name="ParameterList" ...>
<Border BorderBrush="Black" BorderThickness="1" Height="100">
<!-- I don't know if this binding expression is correct -->
<ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:ParameterList}}, Path=Parameters}">
<ItemsControl.ItemTemplate>
<Border>
<!-- The property path defined via "ParameterNameMember" should be bound. -->
<TextBlock Text="{Binding ???}" />
<!-- The property path defined via "ParameterValueMember" should be bound. -->
<!-- The value edited in this TextBox should be transferred to the ViewModel. -->
<TextBox Text="{Binding ???}" />
</Border>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</UserControl>
UserControl code behind:
public partial class ParameterList : UserControl
{
public IEnumerable Parameters
{
get => (IEnumerable)GetValue(ParametersProperty);
set => SetValue(ParametersProperty, value);
}
public string ParameterNameMember
{
get => (string)GetValue(ParameterNameMemberProperty);
set => SetValue(ParameterNameMemberProperty, value);
}
public string ParameterValueMember
{
get => (string)GetValue(ParameterValueMemberProperty);
set => SetValue(ParameterValueMemberProperty, value);
}
public static readonly DependencyProperty ParametersProperty =
DependencyProperty.Register("Parameters", typeof(object),
typeof(ParameterList), new PropertyMetadata(default(IEnumerable)));
public static readonly DependencyProperty ParameterNameMemberProperty =
DependencyProperty.Register("ParameterNameMember", typeof(string),
typeof(ParameterList), new PropertyMetadata(""));
public static readonly DependencyProperty ParameterValueMemberProperty =
DependencyProperty.Register("ParameterValueMember", typeof(string),
typeof(ParameterList), new PropertyMetadata(""));
public ParameterList()
{
InitializeComponent();
}
}
I want to use the control as follows:
<uc:ParameterList
x:Name="ParameterList"
Parameters="{Binding Parameters}"
ParameterNameMember="Name"
ParameterValueMember="Value" />
Since I don't have that much experience with WPF, I need some help with the data binding. I would be very grateful if I could get some useful suggestions.

WPF change value of a child inside UserControl

I need to change a value from MainWindow of a Control inside my CustomControl.
So lets say I want to change the Labels Content inside UserControl MyControl from MainWindow.xaml.
Example:
<UserControl x:Class="XXXXX.MyUserControl"
.
.
.
>
<Grid>
<Label x:Name="TestLabel"/>
</Grid>
</UserControl>
And in MainWindow.xaml:
<MyUserControl x:Name="TestControl" />
Now how can I access Label.Content from Xaml Designer in MainWindow.xaml?
I didn't find anything out there, so hopefully someone knows how to do that.
Thanks a lot
Expose a custom Property in your UserControl, like below
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
var dpd = DependencyPropertyDescriptor.FromProperty(LabelContentProperty, typeof(MyUserControl));
dpd.AddValueChanged(this, (sender, args) =>
{
_label.Content = this.LabelContent;
});
}
public static readonly DependencyProperty LabelContentProperty = DependencyProperty.Register("LabelContent", typeof(string), typeof(MyUserControl));
public string LabelContent
{
get
{
return GetValue(LabelContentProperty) as string;
}
set
{
SetValue(LabelContentProperty, value);
}
}
}
In xaml of MainWindow
<MyUserControl x:Name="TestControl" LabelContent="Some Content"/>
Added the Following to your UserControl
<UserControl x:Class="XXXXX.MyUserControl"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
.
.
>
Have the User Control Implement INotifyPropertyChanged
Add a Property to the user control like this
Private _LabelText As String
Public Property LabelText() As String
Get
Return _LabelText
End Get
Set(ByVal value As String)
_LabelText = value
OnPropertyChanged("LabelText")
End Set
End Property
Update the Label to Bind from that Property
<Label x:Name="TestLabel" Content="{Binding Path=LabelText}"/>
Then in your MainWindow you can change the property accourdingly
<MyUserControl x:Name="TestControl" LabelText="Testing" />
Then your code behind can also reference that property

Databinding to dependency properties of my user control doesn't work

I am making a user control to represent chosen numbers (like in a lottery). The problem is that when binding to it inside a data template binding does not work.
It works correclty when hardcoding the values.
The errors are of this type and they appear for every dependency property I bind to
Error: BindingExpression path error: 'BackCheckedColor' property not found on 'NumberControlTest.Controls.NumberControl'. BindingExpression: Path='BackCheckedColor' DataItem='NumberControlTest.Controls.NumberControl'; target element is 'NumberControlTest.Controls.NumberControl' (Name='null'); target property is 'CheckedBackgroundColor' (type 'String')
What I find strange is that in this section of the error
BindingExpression: Path='BackCheckedColor' DataItem='NumberControlTest.Controls.NumberControl'
It suggests that it is trying to find the BackCheckedColor in the usercontrol itself. That does not make sense to me. Can somebody help??
User Control Xaml
<UserControl.Resources>
<local:CheckedToBrushConverter x:Key="CheckedToBrushConverter"
CheckedBackgroundColor="{Binding CheckedBackgroundColor}"
CheckedForegroundColor="{Binding CheckedForegroundColor}"
UncheckedBackgroundColor="{Binding UncheckedBackgroundColor}"
UncheckedForegroundColor="{Binding UncheckedForegroundColor}"/>
</UserControl.Resources>
<Grid Tapped="Grid_Tapped">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="16*"/>
<ColumnDefinition Width="130*"/>
<ColumnDefinition Width="16*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="16*"/>
<RowDefinition Height="130*"/>
<RowDefinition Height="30*"/>
</Grid.RowDefinitions>
<Ellipse x:Name="Ellipse" Grid.RowSpan="3" Grid.ColumnSpan="3" Fill="{Binding IsChecked, Converter={StaticResource CheckedToBrushConverter}, ConverterParameter=background}"/>
<Viewbox Grid.Row="1" Grid.Column="1">
<TextBlock x:Name="NumberBlock" TextWrapping="Wrap" FontFamily="Segoe UI" Text="{Binding NumberValue}" Foreground="{Binding IsChecked, Converter={StaticResource CheckedToBrushConverter}, ConverterParameter=foreground}" />
</Viewbox>
</Grid>
User control code behind
public sealed partial class NumberControl : UserControl
{
public NumberControl()
{
this.InitializeComponent();
this.DataContext = this;
}
public string UncheckedBackgroundColor
{
get { return (string)GetValue(UncheckedBackgroundColorProperty); }
set { SetValue(UncheckedBackgroundColorProperty, value); }
}
// Using a DependencyProperty as the backing store for UncheckedBackgroundColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UncheckedBackgroundColorProperty =
DependencyProperty.Register("UncheckedBackgroundColor", typeof(string), typeof(NumberControl), new PropertyMetadata(string.Empty));
public string CheckedBackgroundColor
{
get { return (string)GetValue(CheckedBackgroundColorProperty); }
set { SetValue(CheckedBackgroundColorProperty, value); }
}
// Using a DependencyProperty as the backing store for CheckedBackgroundColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CheckedBackgroundColorProperty =
DependencyProperty.Register("CheckedBackgroundColor", typeof(string), typeof(NumberControl), new PropertyMetadata(string.Empty));
plus more dependency properties like those.
MainPage xaml
<Page.Resources>
<DataTemplate x:Key="NumberTemplate">
<Grid>
<controls:NumberControl
UncheckedBackgroundColor="{Binding BackUncheckedColor}"
UncheckedForegroundColor="{Binding ForeUncheckedColor}"
CheckedBackgroundColor="{Binding BackCheckedColor}"
CheckedForegroundColor="{Binding ForeCheckedColor}"
NumberValue="{Binding Value}"
IsChecked="{Binding IsChecked}"
HorizontalAlignment="Center"
VerticalAlignment="Center" Width="45" Height="45"/>
</Grid>
</DataTemplate>
</Page.Resources>
<Grid Background="#0f455f">
<GridView x:Name="NumbersGridView" ItemTemplate="{StaticResource NumberTemplate}" ItemsSource="{Binding Numbers, Mode=TwoWay}"/>
<Button x:Name="printButton" Content="Print" VerticalAlignment="Bottom" HorizontalAlignment="Center" Click="printButton_Click"/>
</Grid>
Model class which provides the data of the collection bound to the gridview
public class MockNumber
{
public MockNumber(bool isChecked, int value, string backchcolor, string forchcolor, string backunchcolor, string forunchcolor)
{
IsChecked = isChecked;
Value = value;
BackCheckedColor = backchcolor;
ForeCheckedColor = forchcolor;
BackUncheckedColor = backunchcolor;
ForeUncheckedColor = forunchcolor;
}
public bool IsChecked { get; set; }
public int Value { get; set; }
public string BackCheckedColor { get; set; }
public string ForeCheckedColor { get; set; }
public string BackUncheckedColor { get; set; }
public string ForeUncheckedColor { get; set; }
}
EDIT: How the model is instantiated and bound in the MainPage codebehind.
public MainPage()
{
this.InitializeComponent();
this.DataContext = this;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
makelist();
}
void makelist()
{
for (int i = 1; i <= 20; i++)
{
Numbers.Add(new MockNumber(i % 4 == 0 ? true : false, i, "#dead2b", "#000000", "#dead2b", "#f0b60c"));
}
}
private ObservableCollection<MockNumber> numbers = new ObservableCollection<MockNumber>();
public ObservableCollection<MockNumber> Numbers
{
get
{
return numbers;
}
set
{
numbers = value;
}
}
The reason why it's trying to find the 'BackCheckedColor' property from the NumberControl is because you set the user control's datacontext to itself.
public NumberControl()
{
this.InitializeComponent();
this.DataContext = this;
}
You're telling the user control that your data context is itself. It means that when you do the "{Binding}" the path should be a property of the user control which I don't think is a good idea.
I understand that you want to bind some dependency properties to your Model class but I didn't see in your example where you instantiated the model class and use it as your data context.
Another thing to consider, you might want to use a custom control instead of a user control. I can see that you added some dependency properties to your user control but in practice, dependency properties added to custom controls and static classes that has attached properties.
EDIT:
After reading your additional code, I can see that the user control's datacontext was being set to 'this' which is itself. You need to remove that.
public sealed partial class NumberControl : UserControl
{
public NumberControl()
{
this.InitializeComponent();
this.DataContext = this; //Remove this line
}
//...
Then after removing that, you usercontrol should inherit the GridViewItem's Binding or you can explicitly put the datacontext in your DataTemplate.
<DataTemplate x:Key="NumberTemplate">
<Grid>
<controls:NumberControl DataContext="{Binding}" <!--specify the data context-->
UncheckedBackgroundColor="{Binding BackUncheckedColor}"
//..

C# VS : Factoring code into UserControl, using ObservableCollection, and consuming it with Binding

I am factoring some code into UserControls which parameters are bound when consumed. I am meeting difficulties with the use of ObservableCollection as a DependencyProperty.
The example showing the difficulty is a project consisting in a MainWindow with two DependencyProperty:
one representing a String (named "Data") and
another one representing an ObservableCollection (named "Origin");
and a UserControl (named UserControl1) exposing two similar DependencyProperty (named resp. "Liste" and "Noun").
The MainWindow contains a TextBlock which Text is bound to "Data" and a ComboBox which ItemsSource is bound to "Origin". Both are working fine.
Both controls are factored into UserControl1, with the DependencyProperty "Liste" and "Noun" acting as intermediate, and UserControl1 is consumed in MainWindow.
Each DataContext (of MainWindow and of UserControl1) is set to "this".
The trouble is while the factored TextBlock (within UserControl1) is working and showing the content of "Data", the factored ComboBox is not working and its DropDown is empty.
The code of MainWindow.xaml is:
<Window x:Class="ChainedBindingUserControl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350" Width="525"
xmlns:Local="clr-namespace:ChainedBindingUserControl"
>
<StackPanel>
<TextBlock Text="{Binding Data}"
Width="150"
/>
<ComboBox ItemsSource="{Binding Origin}"
Width="150"
/>
<Label Content="--------------------------------------------------"
Width="200"
/>
<Local:UserControl1 Liste="{Binding Origin}"
Noun="{Binding Data}"
Height="50" Width="150"
/>
</StackPanel>
</Window>
Its code behind is :
namespace ChainedBindingUserControl
{
public partial class MainWindow : Window
{
public ObservableCollection<String> Origin
{
get { return (ObservableCollection<String>)GetValue(OriginProperty); }
set { SetValue(OriginProperty, value); }
}
public static readonly DependencyProperty OriginProperty =
DependencyProperty.Register("Origin", typeof(ObservableCollection<String>), typeof(MainWindow),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
public String Data
{
get { return (String)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(String), typeof(UserControl1),
new FrameworkPropertyMetadata("Blablabla", FrameworkPropertyMetadataOptions.AffectsRender));
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
ObservableCollection<String> zog = new ObservableCollection<String>();
zog.Add("A");
zog.Add("B");
zog.Add("C");
Origin = zog;
}
}
}
The file UserControl1.xaml is :
<UserControl x:Class="ChainedBindingUserControl.UserControl1"
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"
mc:Ignorable="d"
Name="root"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<TextBlock Text="{Binding Noun}"
/>
<ComboBox ItemsSource="{Binding Liste}"
/>
</StackPanel>
</UserControl>
Its code behind is :
namespace ChainedBindingUserControl
{
public partial class UserControl1 : UserControl
{
public ObservableCollection<String> Liste
{
get { return (ObservableCollection<String>)GetValue(ListeProperty); }
set { SetValue(ListeProperty, value); }
}
public static readonly DependencyProperty ListeProperty =
DependencyProperty.Register("Liste", typeof(ObservableCollection<String>), typeof(UserControl1),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
public String Noun
{
get { return (String)GetValue(NounProperty); }
set { SetValue(NounProperty, value); }
}
public static readonly DependencyProperty NounProperty =
DependencyProperty.Register("Noun", typeof(String), typeof(UserControl1),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender));
public UserControl1()
{
InitializeComponent();
this.DataContext = this;
}
}
}
`
EDIT
According to the pieces of information and snippets provided on http://sshumakov.com/2012/11/13/how-to-create-dependency-properties-for-collections/ , I changed the code behind of UserControl1 into
public partial class UserControl1 : UserControl
{
public IList Liste
{
get { return (List<String>)GetValue(ListeProperty); }
set { SetValue(ListeProperty, value); }
}
public static readonly DependencyProperty ListeProperty =
DependencyProperty.Register("Liste", typeof(IList), typeof(UserControl1),
new FrameworkPropertyMetadata(new List<String>(), FrameworkPropertyMetadataOptions.AffectsRender));
public String Noun
{
get { return (String)GetValue(NounProperty); }
set { SetValue(NounProperty, value); }
}
public static readonly DependencyProperty NounProperty =
DependencyProperty.Register("Noun", typeof(String), typeof(UserControl1),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsRender));
public UserControl1()
{
InitializeComponent();
this.DataContext = this;
SetValue(ListeProperty, new List<String>());
}
}
but it is still not working.
The trouble doesn't come from the DataContext since the TextBlock works as expected.
The trouble here is specific: why a DependecyProperty acting as an intermediate for Binding is working when the property is of type String while it doesn't work when it is of type ObservableCollection (or List, etc).
Thanks in advance for any explanation.
Your problem is in the UserControl's xaml, here:
<TextBlock Text="{Binding Noun}"
/>
<ComboBox ItemsSource="{Binding Liste}"
/>
These binding expressions are attempting to locate Noun and Liste properties on the DataContext of your UserControl, not on the UserControl itself. You need to specify a different target. Since you've already named your UserControl element, you can replace the bindings with this:
<TextBlock Text="{Binding ElementName=root, Path=Noun}"
/>
<ComboBox ItemsSource="{Binding ElementName=root, Path=Liste}"
/>
Imagine that you are creating control that has property that accepts collection:
public class CustomControl : Control
{
public IEnumerable<string> Items { get; set; }
}
If you want property Items to act as binding target you must change it to be dependency property:
public class CustomControl : Control
{
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register("Items", typeof(IEnumerable<string>), typeof (CustomControl), new PropertyMetadata(new List<string>()));
public IEnumerable<string> Items
{
get { return (IEnumerable<string>) GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
}
As you can see, we changed this property to dependency property and supplied new instance of List class as default parameter. As it turned out, this default value will be used on class level (i.e. it will be created only once and each instance of CustomControl will have reference to the same collection). Therefore, we need one modification:
public class CustomControl : Control
{
public CustomControl()
{
Items = new List<string>();
}
}
Now you can use this control and supply value for Items property via binding:
<Grid>
<DependencyPropertiesCollection:CustomControl Items="{Binding ItemsSource}"/>
</Grid>
Currently this control has one limitation – Items property can’t be filled directly in XAML like this code does:
<Grid>
<DependencyPropertiesCollection:CustomControl>
<DependencyPropertiesCollection:CustomControl.Items>
<System:String>Item 1</System:String>
<System:String>Item 2</System:String>
<System:String>Item 3</System:String>
<System:String>Item 4</System:String>
<System:String>Item 5</System:String>
</DependencyPropertiesCollection:CustomControl.Items>
</DependencyPropertiesCollection:CustomControl>
</Grid>
To fix this, you need to change property type from IEnumerable to IList:
public class CustomControl : Control
{
public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof (IList), typeof (CustomControl), new PropertyMetadata(new List<string>()));
public IList Items
{
get { return (IList)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
public CustomControl()
{
Items = new List<string>();
}
}
Credits:-
http://sshumakov.com/2012/11/13/how-to-create-dependency-properties-for-collections/

WPF checkbox binding

While it is trivial to store a checkbox's checked state in a variable using the checkbox's Click event, how would I do it via databinding? All the examples I have found have the UI updated from some datasource, or bind one control to another; I want to update a member variable when the checkbox is clicked.
TIA for any pointers...
You must make your binding bidirectional :
<checkbox IsChecked="{Binding Path=MyProperty, Mode=TwoWay}"/>
You need a dependency property for this:
public BindingList<User> Users
{
get { return (BindingList<User>)GetValue(UsersProperty); }
set { SetValue(UsersProperty, value); }
}
public static readonly DependencyProperty UsersProperty =
DependencyProperty.Register("Users", typeof(BindingList<User>),
typeof(OptionsDialog));
Once that is done, you bind the checkbox to the dependency property:
<CheckBox x:Name="myCheckBox"
IsChecked="{Binding ElementName=window1, Path=CheckBoxIsChecked}" />
For that to work you have to name your Window or UserControl in its openning tag, and use that name in the ElementName parameter.
With this code, whenever you change the property on the code side, you will change the textbox. Also, whenever you check/uncheck the textbox, the Dependency Property will change too.
EDIT:
An easy way to create a dependency property is typing the snippet propdp, which will give you the general code for Dependency Properties.
All the code:
XAML:
<Window x:Class="StackOverflowTests.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" x:Name="window1" Height="300" Width="300">
<Grid>
<StackPanel Orientation="Vertical">
<CheckBox Margin="10"
x:Name="myCheckBox"
IsChecked="{Binding ElementName=window1, Path=IsCheckBoxChecked}">
Bound CheckBox
</CheckBox>
<Label Content="{Binding ElementName=window1, Path=IsCheckBoxChecked}"
ContentStringFormat="Is checkbox checked? {0}" />
</StackPanel>
</Grid>
</Window>
C#:
using System.Windows;
namespace StackOverflowTests
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public bool IsCheckBoxChecked
{
get { return (bool)GetValue(IsCheckBoxCheckedProperty); }
set { SetValue(IsCheckBoxCheckedProperty, value); }
}
// Using a DependencyProperty as the backing store for
//IsCheckBoxChecked. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsCheckBoxCheckedProperty =
DependencyProperty.Register("IsCheckBoxChecked", typeof(bool),
typeof(Window1), new UIPropertyMetadata(false));
public Window1()
{
InitializeComponent();
}
}
}
Notice how the only code behind is the Dependency Property. Both the label and the checkbox are bound to it. If the checkbox changes, the label changes too.
Hello this is my first time posting so please be patient:
my answer was to create a simple property:
public bool Checked { get; set; }
Then to set the data context of the Checkbox (called cb1):
cb1.DataContext = this;
Then to bind the IsChecked proerty of it in the xaml
IsChecked="{Binding Checked}"
The code is like this:
XAML
<CheckBox x:Name="cb1"
HorizontalAlignment="Left"
Margin="439,81,0,0"
VerticalAlignment="Top"
Height="35" Width="96"
IsChecked="{Binding Checked}"/>
Code behind
public partial class MainWindow : Window
{
public bool Checked { get; set; }
public MainWindow()
{
InitializeComponent();
cb1.DataContext = this;
}
private void myyButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(Checked.ToString());
}
}
Should be easier than that. Just use:
<Checkbox IsChecked="{Binding Path=myVar, UpdateSourceTrigger=PropertyChanged}" />
if you have the property "MyProperty" on your data-class, then you bind the IsChecked like this.... (the converter is optional, but sometimes you need that)
<Window.Resources>
<local:MyBoolConverter x:Key="MyBoolConverterKey"/>
</Window.Resources>
<checkbox IsChecked="{Binding Path=MyProperty, Converter={StaticResource MyBoolConverterKey}}"/>
This works for me (essential code only included, fill more for your needs):
In XAML a user control is defined:
<UserControl x:Class="Mockup.TestTab" ......>
<!-- a checkbox somewhere within the control -->
<!-- IsChecked is bound to Property C1 of the DataContext -->
<CheckBox Content="CheckBox 1" IsChecked="{Binding C1, Mode=TwoWay}" />
</UserControl>
In code behind for UserControl
public partial class TestTab : UserControl
{
public TestTab()
{
InitializeComponent(); // the standard bit
// then we set the DataContex of TestTab Control to a MyViewModel object
// this MyViewModel object becomes the DataContext for all controls
// within TestTab ... including our CheckBox
DataContext = new MyViewModel(....);
}
}
Somewhere in solution class MyViewModel is defined
public class MyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool m_c1 = true;
public bool C1 {
get { return m_c1; }
set {
if (m_c1 != value) {
m_c1 = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("C1"));
}
}
}
}
No backend and ViewModel Code:
I made such check box to control other control's visibility.
<CheckBox x:Name="rulerCheckbox" Content="Is Ruler Visible" IsChecked="True"/>
and in the other control, I added such binding:
Visibility="{Binding IsChecked, ElementName=rulerCheckbox, Mode=TwoWay, Converter={StaticResource BoolVisConverter}}">

Categories

Resources