<Page>
<local:AControl Visibility="{Binding ElementName=SendPushWindow,Path=DataContext.SelectedItem,Converter={StaticResource ToVisibilityConverter},ConverterParameter=A}"/>
<local:BControl Visibility="{Binding ElementName=SendPushWindow,Path=DataContext.SelectedItem,Converter={StaticResource ToVisibilityConverter},ConverterParameter=B}"/>
<local:CControl Visibility="{Binding ElementName=SendPushWindow,Path=DataContext.SelectedItem,Converter={StaticResource ToVisibilityConverter},ConverterParameter=C}"/>
<local:DControl Visibility="{Binding ElementName=SendPushWindow,Path=DataContext.SelectedItem,Converter={StaticResource ToVisibilityConverter},ConverterParameter=D}"/>
<local:EControl Visibility="{Binding ElementName=SendPushWindow,Path=DataContext.SelectedItem,Converter={StaticResource ToVisibilityConverter},ConverterParameter=E}"/>
</Page>
And in parent page public InterfaceType SelectedItem { get; set; }
Hello,
I have some controls which visibility depends on SelectedItem type, ToVisibilityConverter just change the visibility depending on ConverterParameter.
This example works, but of course if the item underlying in SelectedItem is changed, there are binding errors on the other controls which visibility is collapsed, that's obvious, because properties don't match. So my goal is to remove that binding errors - to do that I should do something that shouldn't create or update control if it is not of correct type. How to achieve it? How to handle these solutions? For example kind of injecting but how?
Ok I found an easy solution:
<ContentControl Content="{Binding ElementName=SendPushWindow,
Path=DataContext.SelectedItem,
Converter={StaticResource ToTemplateConverter}}">
And in converter just return that control :) Sorry for bothering
Related
I have a the following three items in my xaml that have there visibility changed depending on a boolean property located in the DataContext of the page.
<worklist:PhysicianQuickInsert Visibility="{Binding IsInsertingPhysician, Converter={StaticResource NullEmptyFalseToInvisibileConverter}}" />
<shared:LoadingIndicator Visibility="{Binding IsInsertingPhysician, Converter={StaticResource NullEmptyFalseToInvisibileConverter}}" />
<TextBlock Text="Test" Foreground="Red" Visibility="{Binding IsInsertingPhysician, Converter={StaticResource NullEmptyFalseToInvisibileConverter}}" />
The TextBlock and LoadingIndicator are becoming visible/collapsed, but the PhysicianQuickInsert fails to do anything.
I have verified that the getter of the boolean property is never retrieved for the PhysicianQuickInsert.
Why would this happen? PhysicianQuickInsert is a usercontrol, as is the LoadingingIndicator.
This can happen if you defined a new Visibility property on your UserControl. If you've done this, you may need to make sure that it's binding two-way by default, has a proper setter, etc.
Following the comments on my answer, this issue was that this user control binds to a another datacontext (different type) within it. I added a RelativeSource and it worked.
Thanks everyone!
I have a Tree View, I am using a Text block inside my Tree view Item.I can not able to bind text for text block When I used "Data context" for my Treeview Item. Can any one help me in fixing this Issue.
here is my xaml code..
<TreeViewItem ItemsSource="{Binding}" DataContext="{Binding XYZ}">
<TreeViewItem.Header>
<StackPanel>
<Image Source="abc.png" />
<TextBlock Text="{Binding BindContent}"></TextBlock>
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
in My View Model, I am using
private string _content;
public string BindContent
{
get{ return _content;}
set{_content= value;}
}
In my constructor I am setting value for Content...
It is working fine when I used static content (or) when I am not using
Data context for Treeview Item. but for some other reasons i need to use Data Context.
How can I bind Content for Text block When I used Data Context for Tree view Item...
Thanks in Advance.
I think the problem could be that you are not implementing the INotifyPropertyChanged or you are not raising the notify property changed event. By default the text is null, then you set it in your ViewModel's constructor, but if it is not INotifyPropertyChanged then the view will not be notified.
Hope this could helps you to solve the problem...
Two things you can do,
Make sure your viewmodel implements INotifyPropertyChanged as suggested by Raul Otario and you raise the event on property change,
Secondly, you can use relative source in your binding something like, UserControl if your xaml is on usercontrol else Window
<TextBlock Text="{Binding Path=DataContext.BindContent,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}}"/>
Hope it helps...
I can't seem to pick my way through Telerik's terrible documentation for binding through an MVVM situation. We've got the standard view, and view model. The viewmodel exposes a property, 'Body' that is supposed to represent what the user is typing. Here are the relevant lines of xaml:
<telerik:DocxDataProvider
x:Name="DocxProvider"
RichTextBox="{Binding ElementName=editor}"
Docx="{Binding Body, Mode=TwoWay,
UpdateSourceTrigger=LostFocus}" />
<telerik:RadRichTextBox
Grid.Row="1"
x:Name="editor"
Margin="0"
AllowDrop="True"
ShowComments="False"
MinWidth="800"
MinHeight="300"
MaxWidth="1024"
MaxHeight="1200"
HorizontalAlignment="Left"
HorizontalContentAlignment="Left"
Width="790"
Padding="20,20,0,20"
TabIndex="10"
Cursor="IBeam"
IsSpellCheckingEnabled="True" >
</telerik:RadRichTextBox>
But when I set a break point on Body, it never gets hit. What property do I need to bind to so that my view model actually gets the content of the text box?
Have you tried binding to Rtf property of telerik:RadRichTextBox; another thing can be the ordering of your elements, can you try declaring <telerik:RadRichTextBox before <telerik:DocxDataProvider
Also have a look at this thread on telerik forum -
http://www.telerik.com/community/forums/wpf/richtextbox/binding-document.aspx
Did you remember to set the datacontext in the constructor of the xaml.cs file:
public View(ViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
This is how you hook up the viewmodel to the view.
I have another WPF databinding question... one that I haven't found an answer to anywhere, and this surprises me since it seems like it is very basic.
Essentially, I have a string in code behind that I would like to establish a two-way binding with with a textbox in my GUI. I thought it was a simple matter of creating a DependencyProperty in the code behind, and then tying it to the TextBox via a Source binding. The problem is, I can't get one or both parts right.
Here is my DependencyProperty definition from the code behind:
public static readonly DependencyProperty FilePathProperty = DependencyProperty.Register( "FilePath", typeof(string), typeof(Window1));
public string FilePath
{
get { return (string)GetValue(FilePathProperty); }
set { SetValue( FilePathProperty, value); }
}
And here is my XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ReportingInterface Test Application" Height="300" Width="536">
<Menu DockPanel.Dock="Top">
<MenuItem Name="menu_plugins" Header="File">
<MenuItem Header="Open">
<StackPanel Orientation="Horizontal">
<Label>File location:</Label>
<TextBox Name="text_filepath" Width="100" Text="{Binding Source=FilePath, Path=FilePath, Mode=TwoWay}"></TextBox>
<Button Margin="3" Width="20">...</Button>
</StackPanel>
</MenuItem>
</MenuItem>
</Menu>
The part I know is obviously wrong is the Binding part... I hate to waste people's time here with this question, but I honestly have come up short with every search (but now at least this request will populate subsequent google searches). :)
Thank you!
When you defined a binding in XAML, it binds to whatever is set as the DataContext for the object (or it's parent).
This typically means you'd set the DataContext of the Window to some class, and then the binding will work:
<TextBox Name="text_filepath" Width="100" Text="{Binding Path=FilePath, Mode=TwoWay}" />
You can fix this by adding, in the Window's constructor:
this.DataContext = this;
That will make the binding work against the window itself.
Alternatively, you can setup the binding to bind against a specific source object. If, in this case, you wanted to be able to use something else as the DataContext, but still want to bind to a Dependency Property defined in your Window, you could do:
<TextBox Name="text_filepath" Width="100" Text="{Binding Path=FilePath, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"></TextBox>
This works by telling the binding to find the first ancestor of type "Window", and bind it the "FilePath" property on that object.
For what it's worth, I would recommend looking into the M-V-VM pattern (Model, View, ViewModel)- essentially, what you do is have this class that serves as the DataContext for your XAML, and all your fun exposed properties/commands/what have you are exposed as public members of that class (called a ViewModel).
Here's a good overview webcast:
MVVM video
And here's another from MSDN mag:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
I'm trying to make an Address control that has an IsReadOnly property, which will make every TextBox inside read only when set to true.
<my:AddressControl Grid.Column="1" Margin="5" IsReadOnly="True"/>
I've managed to do this just fine with a dependency property and it works.
Here's a simple class with the dependency property declared :
public partial class AddressControl : UserControl
{
public AddressControl()
{
InitializeComponent();
this.DataContext = this;
}
public static readonly DependencyProperty IsReadOnlyProperty =
DependencyProperty.Register("IsReadOnly", typeof(bool),
typeof(AddressControl), null);
public bool IsReadOnly
{
get { return (bool)GetValue(IsReadOnlyProperty); }
set { SetValue(IsReadOnlyProperty, value); }
}
}
In the XAML for this codebehind file I have a Textbox for each address line:
<TextBox IsReadOnly="{Binding IsReadOnly}" Text="{Binding City, Mode=TwoWay}"/>
<TextBox IsReadOnly="{Binding IsReadOnly}" Text="{Binding State, Mode=TwoWay}"/>
<TextBox IsReadOnly="{Binding IsReadOnly}" Text="{Binding Zip, Mode=TwoWay}"/>
Like i said this works just fine.
The problem is that the Address control itself is bound to its parent object (I have several addresses I am binding).
<my:AddressControl DataContext="{Binding ShippingAddress, Mode=TwoWay}" IsReadOnly="True">
<my:AddressControl DataContext="{Binding BillingAddress, Mode=TwoWay}" IsReadOnly="True">
The problem is that as soon as I set DataContext to something other than 'this' then the binding for IsReadOnly breaks. Not surprising because its looking for IsReadOnly on the Address data entity and it doesn't exist or belong there.
I've tried just about every combination of binding attributes to get IsReadOnly to bind to the AddressControl obejct but can't get it working.
I've tried things like this, but I can't get IsReadOnly to bind independently to the AddressControl property instead of its DataContext.
<TextBox IsReadOnly="{Binding RelativeSource={RelativeSource Self}, Path=IsReadOnlyProperty}" Text="{Binding City, Mode=TwoWay}" />
I think I'm pretty close. What am I doing wrong?
With this answer (actually my own answer to a similar question) I have a good [better] solution.
I still have to iterate through the textboxes, but I don't have to set the actual value. I can create bindings in the codebehind - just not with XAML.
I think you're stuck, at least, if you want to do this just via binding. My guess is that you're going to have to resort to code-behind, presumably by iterating through your child textbox controls and setting their IsReadOnly propert as a side-effect of your Address control's IsReadOnly property.
Unlike some folks who think that any code sitting in a code-behind file is effectively an admission of failure, I don't get religious about it: if throwing some code into a code-behind is the easiest way to do something, that's where I put my code. On the contrary, if I have to spend half a day trying to figure out how to do something via binding that I could do in five minutes with a code-behind, that's failure, IMO.