get value of a textbox a resource dictionary xaml / vb.net - wpf

Well i have a little resource dictionary and a little class which manages the code behind, here is the code:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyResources">
<DataTemplate x:Key="Template1">
<TextBox Name = TB_1 textchanged="handle_text" Margin="10,50 />
<Button Name="BT_1" Content="test1" Margin="10,10" />
</Grid>
</DataTemplate>
</ResourceDictionary>
The dataTemplate is displayed in a other class in a contentcontrol, that runs properly.
But in the class MyResources, i would like to get the text value of the textbox TB_1 with the handle_text function when the event textchanged is risen but it seems that the class MyResources doesn't see the variable textbox with the name TB_1 (and all others variables).
Is it possible to do this?
I give you thanks for your help.

Related

How to bind to type Window as a DataTemplate

My WPF application uses a Resource Dictionary. I'm also using MVVM.
I am binding to a ResourceDictionary, but want to bind my MainWindow ViewModel to the MainWindow (of type Window) but MVVM won't let me as MainWindow it's not type UserControl.
<Grid.Resources>
<ResourceDictionary Source="Resources\ResourceDictionary.xaml" />
</Grid.Resources>
<Grid.DataContext>
<Binding Source="{StaticResource Mwvm}" />
</Grid.DataContext>
</Grid>
This means I can't do this
<DataTemplate DataType="{x:Type viewModel:MainWindowViewModel}">
<root:MainWindow x:Key="Mwvm" />
</DataTemplate>
Does any one know how I can do the same thing but when the object is a Window and only using XAML (I know I can do this with code behind in the app.xaml onstartup())?
EDIT
To make this very clear, I know that within my MainWindow I can declare a namespace to my ViewModel, but is this the correct way when the namespace is already referenced in my ResourceDictionary and I'm referencing my ResourceDictionary.
Uhm how about?
<Window>
<Window.DataContext>
<someNs:YourVmClass /> <!-- calls the empty c_tor of the class-->
</Window.DataContext>
</Window>
(I'm not sure, if I understood your question. But I guess, that's what you really want.)
According to your edit:
Sure you could do something like
<!-- Define an instance of your VM in the ResourceDictionary -->
<ResourceDictionary>
<someNs:YourVmClass x:Key="InstOfYourVmClass" />
</ResourceDictionary>
In your view you could do something like this.
<Grid>
<Grid.Resources>
<ResourceDictionary Source="Resources\ResourceDictionary.xaml" />
</Grid.Resources>
<Grid.DataContext>
<StaticResource ResourceKey="InstOfYourVmClass" />
</Grid.DataContext>
</Grid>
But I would strongly recommend not to choose this approach. Problem is, everytime you're referencing this ResourceDictionary the current instance InstOfYourVmClass will be overwritten by a new instantiated version.

Dynamically load different UserControls based on object type via data binding in xaml

Is there some way in WPF to get the same functionality DataTemplateSelector gives you, but for UserControls?
Say I have a StackView to which I want to bind an IEnumerable of objects. What I'd like to do is somehow have a mapping that, for each object type in the bound IEnumerable, looks at the object type and determines what UserControl to add to the StackView.
So, given three classes:
public class House : Building{}
public class Apartment : Building{}
public class Tent : Building{}
where each class inherits from Building and has its own defined UserControl, I'd like to set DataContext to an IEnumerable<Building> and somehow get the StackView to populate its set of children with the type-specific UserControl.
I'd like to do this with as little code behind as possible. The more data binding and XAML duct tape the better.
You can use complex user controls in a DataTemplate; just declare the DataTemplate as your UserControl.
Example:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
Title="MainWindow" Height="300" Width="300" Name="UI" >
<Window.Resources>
<DataTemplate DataType="{x:Type local:House}" >
<local:HouseUserControl DataContext="{Binding}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Apartment}">
<local:ApartmentUserControl DataContext="{Binding}"/>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding ElementName=UI, Path=ListOfBuildings}" />
</Grid>
</Window>
I'm not sure I see the problem. Just create DataTemplates for each type in your resources somewhere and WPF will use them automatically to render each type.

WPF implicit DataTemplate declared in App.xaml won't take effect

In the MainWindow.xaml, I set:
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
In the App.xaml file, I added the following:
<Application.Resources>
<DataTemplate DataType="vm:MainViewModel">
<v:MainView/>
</DataTemplate>
</Application.Resources>
I was hoping the MainWindow will automatically load and show the MainView with its DataContext property set to the windows's one (which was set to MainViewModel at design-time as above), but it won't work - the MainWindow doesn't use the DataTemplate set in App.xaml.
Any better ideas for this scenario?
You should make a minor changes -
First, in your window. Try this:
<Window>
<!-- setup window... -->
<ContentPresenter>
<ContentPresenter.Content>
<vm:MainViewModel/>
</ContentPresenter.Content>
</ContentPresenter>
</Window>
This creates a single content item within your Window. DataTemplates work by mapping content to a new View - in this case, since the Content here is the MainViewModel, it will automatically create and instantiate a new MainView for you. Setting the DataContext will not trigger DataTemplates, since you're never making the ViewModel "content" of an object.
You can shorten this by just setting the Window's Content directly, if you prefer:
<Window>
<Window.Content>
<vm:MainViewModel/>
</Window.Content>
</Window>
Or, even, binding the Content to the DataContext (though this only makes sense if you need the DataContext set for some other purpose):
<Window Content="{Binding}">
<Window.DataContext>
<vm:MainViewModel/>
</Window.DataContext>
</Window>
I think you need
<DataTemplate DataType="{x:Type vm:MainViewModel}">
EDIT:
I really don't think I'm wrong, the code
<Window.DataContext>
<WpfApplication1:ViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate DataType="{x:Type WpfApplication1:ViewModel}">
<TextBlock>Custom template</TextBlock>
</DataTemplate>
</Window.Resources>
<ContentPresenter Content="{Binding}" />
shows “Custom template”. If I remove the x:Type, what's shown instead is “WpfApplication1.ViewModel”, which is the result of calling ToString() on the view model object. This is used in the absence of a DataTemplate.

Silverlight - Setting DataContext in XAML rather than in constructor?

How can I set the DataContext on my Grid in XAML, instead of in the constructor?
Here is how I do it in the constructor (LayoutRoot is the XAML Grid defined in the XAML):
this.LayoutRoot.DataContext = this.HPVM;
I would prefer to do it right in the XAML, but I do not know how to reference the HPVM object in XAML. HPVM is a public property on the USerControl class.
It works fine as listed above, but again, I just want to know how to properties of the UserControl class in XAML, rather than always having to do it in code.
Here is all the relevant code:
<UserControl x:Class="SilverlightApplication1.SLHolePattern" x:Name="HolePatternsControl"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
xmlns:local="clr-namespace:SilverlightApplication1"
xmlns:GeoPatterns="clr-namespace:GeoPatterns"
Height="700">
<UserControl.Resources>
...
And here is my constructor where the DataContext is currently set:
namespace SilverlightApplication1
{
public partial class SLHolePattern : UserControl, INotifyPropertyChanged
{
public HolePatternsViewModel HPVM;
public SLHolePattern()
{
InitializeComponent();
this.HPVM=new HolePatternsViewModel();
this.LayoutRoot.DataContext = this.HPVM;
...more code here
}
It all works fine, but I just want to learn how to set the DataContext in XAML, not in code.
The answer Chris gave works just fine.
I have tested and it worked for me.
You can instantiate your class in XAML (within the UserControl.Resources) and
then bind the datacontext to a static resource.
Follow code:
<UserControl ...>
<UserControl.Resources>
<myNS:MyClass x:Name="TheContext" x:Key="TheContext"></myNS:MyClass>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource TheContext}" >
<TextBlock Text="{Binding Path=Field1}">
</TextBlock>
</Grid>
</UserControl>
The following monstrosity works in Silverlight 4
<UserControl
DataContext="{Binding HPVM, RelativeSource={RelativeSource Self}}">
<UserControl.DataContext>
<vm:ThisUCViewModel />
</UserControl.DataContext>
try something like this.....
<Grid DataContext="{Binding Path=HPVM}">
</Grid>
where HPVM is a public member of this--> your form etc.
Create the instance of your class in the xaml, by adding something like this to your resources section.... (don't forget to add your xmlns namespace)
<my:bogart x:Key="franken"/>
then, bind the data context to the static resource you just added....
<Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource franken}">
<TextBox Background="Red" Foreground="White" Text="{Binding Path=sum}" />
</Grid>
In Silverlight 4, I was able to get this working by doing the following:
Give the Page/UserControl an x:Name="myPage"
In your control binding use normal Element bidning syntax. In my case I want to bind to an observable collection of objects in my code behind for my ItemsSource property:
<ComboBox
ItemsSource={Binding ElementName=myPage, Path=MyObservableObjectList, Mode=TwoWay}
I haven't tried this with DataContext but know you can do element to element binding for DataContext as I do this for Grids whose context is based on the selected item of some other drop down on the page.
This is not possible (It is possible in WPF with {Binding RelativeSource={RelativeSource Self}}, but Silverlight is more limited.
You have to do it through code.
<UserControl.Resources>
<ResourceDictionary>
<vm:YourModelx:Key="myModel"/>
</ResourceDictionary>
</UserControl.Resources>
<UserControl.DataContext>
<Binding Source="{StaticResource myModel}"/>
</UserControl.DataContext>

How do I bind resource strings in XAML to multiple attributes within the same control?

Is it possible to bind an additional resource string to another attribute within a control. I already have one attribute bound to a resource but also need another. I can't see a way of doing it as I would need an extra DataContext but oviously can only have one.
The additional attribute I need to bind to is Content within the hyperlink control.
The xaml file is as follows:-
<UserControl x:Class="SilverlightApplication1.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mystuff="clr-namespace:my.assembly.name;assembly=my.assembly.name"
Width="100" Height="100">
<UserControl.Resources>
<mystuff:TxtResConv x:Key="TxtResConv" />
<mystuff:TxtResPar x:Key="LabelTitle" ResourceUri="LabelTitle" DefaultValue="default label title" />
<mystuff:TxtResPar x:Key="LinkURL" ResourceUri="LinkURL" DefaultValue="default label title" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<HyperlinkButton DataContext="{StaticResource LinkURL}" x:Name="HyperLink1" Content="NEED TO ADD RESOURCE STRING LABELTITLE HERE !!" NavigateUri="{Binding Mode=OneWay,Converter={StaticResource TxtResConv}}"></HyperlinkButton>
</Grid>
</UserControl>
Thanks in advance.
You use the Binding syntax to bind to the Content property in the same way you bind to the NavigateUri property. If it comes from a different source than LinkUri then you specify that in the binding syntax Source property:
Content="{Binding Source={StaticResource LabelTitle},
Converter={StaticResource TxtResConv}}"

Resources