WPF XAML Binding - wpf

Hello
I have a problem with a binding that I want to do and can't find any information on how to do it.
Basically I want to bind an object to a property of another object.
For example
<TextBox Text="test" Tag="{Binding ElementName=TxtBx2}" x:Name="TxtBx1"/>
<TextBox Text="test" x:Name="TxtBx2"/>
This is kind of weird but it would help on the code that i'm implementing, so on a property of one object I want to have another object bind in xaml.
I don't know if this is possible, any pointers would be helpful
Thanks, Ruben

That is how you do it; you just need to specify the Path.
<TextBox Text="test" Tag="{Binding ElementName=TxtBx2, Path=Text}" x:Name="TxtBx1"/>
<TextBox Text="test" x:Name="TxtBx2"/>
If you are wanting the DataContext of the TextBox; then your Path would change accordingly.
<TextBox Text="test" Tag="{Binding ElementName=TxtBx2, Path=DataContext}" x:Name="TxtBx1"/>
<TextBox Text="test" x:Name="TxtBx2"/>
If you are needing to use the Tag property within a WPF application you might want to re-evaluate your approach as I have yet to use the Tag property since moving from WinForms as that need has been replaced by leveraging the data binding functionality within WPF.
UPDATE:
If your goal is to bind to a given control versus a property on the control; then don't specify the property name within the Path.
Based on your goal; attached behaviors would be a better approach and allow you to wrap the functionality within the extended DataGrid.

<TextBox Text="test" Tag="{Binding ElementName=TxtBx2,Path=Text}" x:Name="TxtBx1"/>
<TextBox Text="test" x:Name="TxtBx2"/>

Assuming you want the value of the Text property of TxtBx1 to be the value of the Text property in TxtBx2, you would use:
<TextBox x:Name="TxtBx1" Text="{Binding ElementName=TxtBx2, Path=Text}" />
<TextBox x:Name="TxtBx2" Text="test" />
Update
Assuming (possibly incorrectly again!) that you want to bind the TxtBx1 element to the Tag of TxtBx2, you would use:
<TextBox x:Name="TxtBx1" Text="test" />
<TextBox x:Name="TxtBx2" Tag="{Binding ElementName=TxtBx1}" Text="test" />
Just out of interest, why do you want to do such a thing?
Update 2
Assuming that you have a Datagrid that you've extended from the wpftoolkit datagrid and a user control that is a pager for that Datagrid, and when you move to another page you need to do some processing on the datagrid, then why don't you just either update the datagrid in your page change event (if using code behind), or update the items that the datagrid is bound to in your page change verb on your view model (if using MVVM)?

Well, it does make sense to bind to an entire object(not to any specific property) with items control such as this:
<ListBox x:Name="pictureBox"
ItemsSource=”{Binding Source={StaticResource photos}}" …>
......
</ListBox>

Related

How to handle Validations on Custom Control

I recently wrote my first custom control, an autocomplete textbox. Its Controltemplate consists of something like this
<Grid >
<Border/>
<TextBlock x:Name="Label"/>
<TextBox x:Name="TextLabel"/>
</Grid>
The first Textblock is used as a Label, the second one shows the content. The TextLabel binds on an Object, let's call it Customer If the underlying search doesn't find a Customer object, I want to show the errortemplate. When defining the TextLabel like this
<TextBox x:Name="PART_Editor"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Validation.ErrorTemplate="{DynamicResource ValidationErrorTemplate}"
Style="{StaticResource TransparentTextBoxStyle}"
Text="{Binding Path=Text, RelativeSource={RelativeSource Mode=TemplatedParent},
Mode=TwoWay, ValidatesOnNotifyDataErrors=True,
NotifyOnValidationError=True,
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}" >
</TextBox>
the Validation is made and the error template of the textbox is shown. Unfortunately the Red Border is only around the inner TextBox and not around the whole custom control which looks just not good.
I was wondering how to achieve two things:
How can the ErrorTemplate of the CustomControl be triggered when one of the child-validations fail?
Do I have to specify all these NotifyOnValidationerror properties or is it possible to catch all errors on entity level and show the same ErrorTemplate
If you need additional Information, please just ask

How do I access a windows control (checkbox) that is created dynamically in a WPF treeview?

I have a WPF Tree View with hierarchical data templates that loads objects and displays them fine. Within the children of the treeview, I am showing the "Name" of the object in the Tree View using a TextBlock, along with a Check Box next to it. Here is my code for reference:
<DockPanel Name="test1" Margin="10,10,0,10" VerticalAlignment="Stretch" Grid.Row="3" Grid.RowSpan="7" Grid.Column="0">
<DockPanel.Resources>
<local:CheckBoxCommand x:Key="cbc"></local:CheckBoxCommand>
<src:TreeViewFilter x:Key="MyList" />
<HierarchicalDataTemplate DataType="{x:Type src:TreeViewParent}" ItemsSource="{Binding Path=OrderAttributes}">
<TextBlock Text="{Binding Path=NameAndCount}" FontSize="24"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type src:OrderAttribute}" ItemsSource="{Binding Path=OrderAttributes}">
<StackPanel Name="test" Orientation="Horizontal" VerticalAlignment="Center">
<CheckBox Command="{StaticResource cbc}"
CommandParameter="{Binding Path=NameAndParent}" Visibility="{Binding Path=CheckBoxVisible}" VerticalAlignment="Center">
</CheckBox>
<TextBlock Text="{Binding Path=NameAndCount}" FontSize="16"/>
</StackPanel>
</HierarchicalDataTemplate>
</DockPanel.Resources>
<TreeView Name="treeView1" BorderThickness="2" ItemsSource="{Binding Source={StaticResource MyList}, UpdateSourceTrigger=PropertyChanged}" TreeViewItem.Selected="filterByBatchStatus"/>
</DockPanel>
When A user checks a checkbox in the tree, certain stuff happens in my application based on which checkbox is checked. The way I know which checkbox is being checked is by passing a paramater through a command, and that parameter is bound to the "NameAndParent" of the object. All of this works fine.
My problem begins when I give the user the option to save which checkboxes have been checked and I save the "Name" of each object next to the checked box into an XML. As you can see, I am only saving the "Name" of the object, but this name has no hook to the checkbox, So I can't go back and "find" the associated checkbox.
When I give the user the option to load one of these saved files, I want to traverse the tree and check the boxes that were saved. The problem is that the checkboxes DONT HAVE A NAME, OR UID, and I cant assign them one through binding because that is not allowed.
Is there anyway to traverse the tree view and somehow compare the saved name to the name of each element child in the tree, and then check that specific checkbox, Or is this something that has to be programmed in a different way?
Just create a boolean IsChecked property in the class that contains your Data, and bind the CheckBox.IsChecked to that. instead of having to manipulate the view, you can more easily manipulate the data it is bound to, removing the need for fancy Visual-Tree operations, and removing the dependency between your application logic and your UI. This is the most important realization of the Model-View-ViewModel Pattern.
If you do not want to introduce UI-related logic (such as the IsChecked property I mentioned) into your Data Model, you will have to introduce a ViewModel in between the Model and the View.

WPF, reference to object used in XAML

I am new to WPF, please do not blame me ;)
I have the following part in XAML:
<ListView x:Name="listView" IsEnabled="{Binding PropertiesEnabled}" Margin="0"
BorderThickness="0" DragDrop1:DropTargetBehavior.IsDropTarget="true"
MinHeight="300" DragDrop1:DropTargetBehavior.DropType="{x:Type UIP:DataItemViewModel}"
ItemsSource="{Binding dataItemCollection}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
AllowDrop="True" KeyDown="listView_KeyDown" MouseUp="listView_MouseUp"
UseLayoutRounding="False" VerticalContentAlignment="Center"
MaxWidth="Infinity" MaxHeight="1000" Grid.Column="1"
HorizontalContentAlignment="Stretch">
In the code behind for the view class, I am able to access listView and most of its properties and attributes like IsEnabled, Margin, ItemsSource etc. However, when it comes to DragDrop1, it is not listed.
The reason why I need to get reference to DragDrop1, which is of type DropTargetBehavior, because some events should be fired programmatically.
What could be the cause of missing DragDrop1? How to I get reference to it?
Cheers.
The property is an AttachedProperty, so it doesn't actually exist as part of the ListView object. You need to use the AttachedProperty class name to access the value, and pass it the ListView as a parameter to get or set the value.
You can get it using DragDrop1.DropTargetBehavior.GetIsDropTarget(listView) or set it using DragDrop1.DropTargetBehavior.SetIsDropTarget(listView, yourValue)

How to define DataContext in my Resource File or under Window.Resource tag?

I have this binding:
<Window x:Name="_local">
<TextBox x:Name="txtVendorName" DataContext="{Binding ElementName=_this, Path=VendorObject}" Width="200" Height="50" BorderBrush="Black" Text="{Binding Path=VendorName}" />
if i have 50 textboxes and label which I need to bind, do I need to put DataContext for all??
Is there a way I can centralize this DataContext and only define Text/Content for my objects?
I don't want to define DatContext to my Grid. So how can I define DataContext in my?
<Window.Resources></Window.Resources>
If I am guessing your actual requirement right, then what you want is all 50 labels and textblocks should be bound to the data context which is VendorObject from _this object. Although I couldnt really guess what _this object is.
Well DataContext is an Inherited Dependency Property (IDP) what they mean is when a visual parent is set with a data context its data context is acquired by all the children below that visual.
So if you put some Panel in your window and set its data context once with your binding DataContext="{Binding ElementName=_this, Path=VendorObject}" and then put all those 50-100 textblocks and labels under that panel then they will automatically acquire that vendor-object as the data context.
So
<StackPanel DataContext="{Binding ElementName=_this, Path=VendorObject}">
<TextBlock Text="{Binding Path=VendorName}" />
<TextBlock Text="{Binding Path=VendorId}" />
<TextBlock Text="{Binding Path=VendorLocation}" />
.... <!--Put all the 50 UI items here to use same data context -->
</StackPanel>
I hope I guessed correctly of what you need.
Now answering you next question,
So how can I define DataContext in my?
<Window.Resources></Window.Resources>
You cant. But you can create an instance of VendorObject class and give it a resource Key, but thats simply a bad design.

Is it possible to bind to a control's property from a datatemplate?

Ok, sounds odd, and there's likely a better way, but I haven't seen it yet.
What I'm trying to do is restyle a ListPicker under Windows Phone 7.
What I need is to
get rid of the header (that's easy, just define a null ListPicker.HeaderTemplate).
Force the picker to always go to full mode when clicked (again, easy, just set the ItemCountThreshold to 1).
Restyle the itemtemplate used when in FullMode (again, easy, just define a FullModeItemTemplate)
Incorporate the ListPicker's "HEADER" property value into the ItemTemplate (since only one item will ever show, i need the header text "embedded" within the one item).
It's that number 4 that I can't seem to get.
I've defined a listpicker like so (i'm directly defining the templates inline instead of in resources for now, just to keep things simple).
<phonekit:ListPicker Header="Header Text" x:Name="ListOfSounds"
SelectedItem="{Binding Path=DepartureChime, Mode=TwoWay, Converter={StaticResource EnumDescriptionToStringConverter}}"
ItemCountThreshold="1">
<phonekit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="Transparent">
<TextBlock Text="{TemplateBinding Header}" />
<TextBlock Text="{Binding}" />
<TextBlock Text=">" />
</StackPanel>
</DataTemplate>
</phonekit:ListPicker.ItemTemplate>
Ignoring all the obvious formatting bits for now, the problem I'm having is that I can't use {TemplateBinding Header} from within a datatemplate. I've used it from a ControlTemplate no problem.
The result of this ItemTemplate should be an item displayed such as
{TextOfHeader}{Content of selected Item}>
I'm just not sure how to go about getting at a property of the templated control (the listpicker in this case).
Any ideas?
Take advantages of RelativeSource:
<TextBlock Text="{Binding Path=Header, RelativeSource={RelativeSource AncestorType={x:Type phonekit:ListPicker}}}" />

Resources