I'm still relatively new to Data Binding in wpf, but despite plunging through all the articles and posts here and elsewhere about what could be wrong, I still have not found a solution. The code below is the prevalent information parsed out of my larger files.
I have made sure everything else is working, including adding a property to retrieve the protected parameter options
to ensure options.FullPath
is in fact getting set/changed on the Browse button's Click
event. I attempted to subscribe to the PropertyChanged
event in the main window with the line test.PropertyChanged = ShowMessage;
, ShowMessage
being a method that triggers a MessageBox
with text in it. I tried multiple variations on the OnPropertyChanged
method from hardcoding it within the calling method to what is displayed here. I even tried setting options
to a default value of ""
just in case it was being weird about that. No luck on anything, and I have no way to acquire C#6 at the moment, so it may very well be that what I have works with the right language updates, but I just can't tell since it doesn't trigger.
Any help or insight would be greatly appreciated!
Object Class:
public class EEOptionSet: INotifyPropertyChanged
{
public EEOptionSet()
{
}
public event PropertyChangedEventHandler PropertyChanged;
private string _fullPath;
public string FullPath
{
get { return _fullPath; }
set
{
if (value != _fullPath)
{
_fullPath = value;
OnPropertyChanged();
}
}
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
Main window's code behind:
public partial class window : Window
{
protected OptionSet options = new Option Set();
private void BrowseFiles(object sender, RoutedEventArgs e)
{
options.FullPath = "Test";
}
}
Textbox and Button instances in the xaml of my main window (extraneous properties like Grid placement, Alignment, etc removed for brevity):
<TextBox x:Name="FullPathText" Text="{Binding (options.FullPath), Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Focusable="False"/>
<uc:ButtonExt x:Name="Browse" Content="..." Click="BrowseFiles"/>
NOTE: I have also tried:
Text="{Binding options.FullPath, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding Path=options.FullPath, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Text="{Binding Path=(_currentOptionSet.FullPath), Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
As well as without the IsReadOnly
and Focusable
properties.
CodePudding user response:
PropertyPath (this is the type of the Binding.Path property) can only be set by the path expression to the public property of the source. And your variable
options
is a protected field.If the source is not explicitly specified in the Binding (there are three ways of setting it: Source, ElementName and RelativeSource), then the Data Context of the element in which the binding is set is used for the source. You did not specify the source in any of these four ways.
An example of setting the Data Context and its use.
Written from assumption:
- the
EEOptionSet
and theOptionSet
classes - are one and the same, and you just made a mistake when copying the code; - the
EEOptionSet
class is declared in the same namespace as yourwindow
.
<Window.DataContext>
<local:EEOptionSet/>
<Window.DataContext>
protected readonly EEOptionSet options;
public window()
{
InitializeComponent();
options = (EEOptionSet) DataContext;
}
<TextBox Text="{Binding FullPath, Mode=OneWay}"
IsReadOnly="True"
Focusable="False"/>
CodePudding user response:
You cannot bind to a protected field.
Set the DataContext
of the window to your field:
public partial class window : Window
{
protected OptionSet options = new OptionSet();
public window()
{
InitializeComponent();
DataContext = options;
}
private void BrowseFiles(object sender, RoutedEventArgs e)
{
options.FullPath = "Test";
}
}
...and remove "options" from the binding path(s) in the XAML markup:
Text="{Binding FullPath, UpdateSourceTrigger=PropertyChanged}"
Alternatively, make options
a public property of the window and set the DataContext
the the window itself:
public partial class window : Window
{
public OptionSet options { get; private set; }
public window()
{
InitializeComponent();
options = = new OptionSet();
DataContext = this;
}
private void BrowseFiles(object sender, RoutedEventArgs e)
{
options.FullPath = "Test";
}
}
Then you should keep the binding path as-is:
Text="{Binding options.FullPath, UpdateSourceTrigger=PropertyChanged}"