C
C#13mo ago
PetitKinder

❔ WPF data binding

Hello, I'm new into wpf developing. I'm trying to bind textbox's data to a property, but it seems to work only for getter, not setter. when I manually set the property and run the app, the textbox is filled by the property. But when, in the app, I change textbox's data, it doesn't update the property. Can somebody help me ?
33 Replies
HimmDawg
HimmDawg13mo ago
Can you show us, how you set up the binding? 🙂
PetitKinder
PetitKinder13mo ago
I will try to do so
PetitKinder
PetitKinder13mo ago
PetitKinder
PetitKinder13mo ago
here a textbox's Text is binded to a Scene property
PetitKinder
PetitKinder13mo ago
PetitKinder
PetitKinder13mo ago
here is the property
PetitKinder
PetitKinder13mo ago
PetitKinder
PetitKinder13mo ago
here is my view
PetitKinder
PetitKinder13mo ago
PetitKinder
PetitKinder13mo ago
and that's the viewModel sorry that's a bit messy
HimmDawg
HimmDawg13mo ago
And where are you setting the DataContext? Furthermore, your second Textbox in ShotTheme.xaml binds to shot which does not exist. You'll have to use Shot. And your Shot property will need to notify the UI when something changed as well Instead of
public string Scene
{
get
{
return _scene;
}
set
{
_scene = value;
OnPropertyChanged();
}
}
public string Scene
{
get
{
return _scene;
}
set
{
_scene = value;
OnPropertyChanged();
}
}
You can use
public string Scene
{
get => _scene;
set => SetProperty(ref _scene, value);
}
public string Scene
{
get => _scene;
set => SetProperty(ref _scene, value);
}
Or even drop the entire property and do just this
[ObservableProperty]
private string _scene;
[ObservableProperty]
private string _scene;
The last example creates some source-generated files, so you'll still be able to use Scene in your code and XAML, even though you never specifically declared it. This makes it more readable :) So for Shot you'll have to choose one of those 3 ways to notify your UI The same applies for Environment So I checked the docs. So most of the time, bindings have a default value for UpdateSourceTrigger of PropertyChanged. However this doesn't apply to textboxes. So you'll 1.) have to set the binding mode of your bindings to TwoWay and then, you'll have to set the UpdateSourceTrigger of your binding to PropertyChanged
PetitKinder
PetitKinder13mo ago
which one ? In the view I'm setting the datacontext for the ShotListViewModel, but I don't know if this is the one you talking about isn't it what the OnpropertyChanged element is for ? for this last exemple, do I need to generate the ObservableProperty class ?
HimmDawg
HimmDawg13mo ago
No, I meant the ShotTheme. Are you setting the datacontext there? Yes, but only for Shot. All other properties wont notify the UI because they dont have this in your VM No, it's part of the CommunityToolkit 🙂 you can use it in every class that derives from ObservableObject ah wait.. i noticed that theres no CommunityToolkit in your usings. ObservableObject is your own implementation then? In that case you'll have to go with the first way ^^
PetitKinder
PetitKinder13mo ago
Using the lambda sign ? I need to set dataContext for a theme ? Because I'm declaring a resourceDictionary for it in the app.xaml
HimmDawg
HimmDawg13mo ago
Nah, just go the same way as with your Scene property I falsely assumed that ObservableObject comes from a package that is widely used in WPF. That package also has a class called ObservableObject and it provides the same functionality. They just added a few extras If you want to bind stuff to the controls in it, then you'll have to have some sort of DataContext
PetitKinder
PetitKinder13mo ago
How do I do so ? What I don't understand, is that the binding works half way
HimmDawg
HimmDawg13mo ago
That's because
Furthermore, your second Textbox in ShotTheme.xaml binds to shot which does not exist. You'll have to use Shot.
Binding to Properties is case-sensitive
PetitKinder
PetitKinder13mo ago
Yeah I know, I was working first on Scene. But scene doesn't work neither
HimmDawg
HimmDawg13mo ago
Side-question. Do you really have to bind data into a theme?
PetitKinder
PetitKinder13mo ago
Well the listView is composed of items defined in the ShotTheme But I suppose it's possible to bind into a theme When the element scene of the object is set in the code, it's working because the textbox is set with the value defined. So the binding is working. But when in the app I modify the property, if I print scene in the output window, the value isn't updated.
HimmDawg
HimmDawg13mo ago
No, I meant: Do you specifically have to bind stuff in your theme? 😄 You'd still need a DataContext to bind data. A resource dictionary can't have a datacontext
PetitKinder
PetitKinder13mo ago
I need to bind the text of textbox which are in the theme, so idk how I can do without it.
HimmDawg
HimmDawg13mo ago
Try to replace the controltemplate with a datatemplate and specify the datatype
PetitKinder
PetitKinder13mo ago
yeah it seems to be a problem around the template, but I'm not used to xaml enough to re-template everything, I think I will have to do some research
HimmDawg
HimmDawg13mo ago
So tl;dr If you just replace "ControlTemplate" with "DataTemplate", you can then assign a DataType to the template. If you do that, you can then use the properties of this datatype in Bindings of control properties within the template
PetitKinder
PetitKinder13mo ago
But can I do that within a style ? because my listView has the property ItemContentStyle set to the style ShotTheme so I need a style, but if I'm right I can't use dataTemplate in a style I will try using a dataTrigger outside Style well no I can't do that
Accord
Accord13mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
PetitKinder
PetitKinder13mo ago
Any other ideas ? i'm stuck
HimmDawg
HimmDawg13mo ago
What about changing the TargetType to ListView and the targeted property of the setter to ItemContainerStyle ? Then you can use DataTemplate
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:models="clr-namespace:WPF_Tests.Models">
<Style TargetType="{x:Type ListView}">
<Style.Setters>
<Setter Property="ItemContainerStyle" >
<Setter.Value>
<Style TargetType="ListViewItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="models:ShotModel">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Scene}" />
<TextBox Text="{Binding Shot}" />
<TextBox Text="{Binding Environment}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:models="clr-namespace:WPF_Tests.Models">
<Style TargetType="{x:Type ListView}">
<Style.Setters>
<Setter Property="ItemContainerStyle" >
<Setter.Value>
<Style TargetType="ListViewItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="models:ShotModel">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Scene}" />
<TextBox Text="{Binding Shot}" />
<TextBox Text="{Binding Environment}" />
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</ResourceDictionary>
PetitKinder
PetitKinder13mo ago
I've tried like that
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:model="clr-namespace:ProductionSheets.MVVM.Model">

<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="TextboxTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>

<Style TargetType="{x:Type ListViewItem}"
x:Key="ShotTheme">
<Style.Setters>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="model:ShotModel">

<Border Background="Transparent"
BorderThickness="0,2,0,2"
BorderBrush="#cccccc"
Margin="20,0,20,0">

<StackPanel Orientation="Horizontal">
<TextBox Style="{StaticResource TextboxTheme}"
Name="Scene"
Text="{Binding Scene}"/>

<TextBox Style="{StaticResource TextboxTheme}"
Name="Shot"
Text="{Binding Shot}"/>
<TextBox Style="{StaticResource TextboxTheme}"
Name="Environment"
Text="{Binding Environment}"/>
</StackPanel>

</Border>

</DataTemplate>
</Setter.Value>
</Setter>

</Style.Setters>
</Style>
</ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:model="clr-namespace:ProductionSheets.MVVM.Model">

<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="TextboxTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>

<Style TargetType="{x:Type ListViewItem}"
x:Key="ShotTheme">
<Style.Setters>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="model:ShotModel">

<Border Background="Transparent"
BorderThickness="0,2,0,2"
BorderBrush="#cccccc"
Margin="20,0,20,0">

<StackPanel Orientation="Horizontal">
<TextBox Style="{StaticResource TextboxTheme}"
Name="Scene"
Text="{Binding Scene}"/>

<TextBox Style="{StaticResource TextboxTheme}"
Name="Shot"
Text="{Binding Shot}"/>
<TextBox Style="{StaticResource TextboxTheme}"
Name="Environment"
Text="{Binding Environment}"/>
</StackPanel>

</Border>

</DataTemplate>
</Setter.Value>
</Setter>

</Style.Setters>
</Style>
</ResourceDictionary>
but it's still not working I will try your version nope, not working So maybe the problem is somewhere else ok so I know where the problem is from. In the shotTheme above, I'm defining a couple of textBox. They all share the same style TextboxTheme. If I remove the style, the binding of Scene is working, the value is updated correctly. What I don't understand is why, with the theme, it's not working.
PetitKinder
PetitKinder13mo ago
maybe it's because I'm redefining the Textbox' Style. How can I tell the textBox's Text property of TextboxTheme = textBox's Text property of ShotTheme ?
Accord
Accord13mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.