Problem in define Orientation Property For My UerControl in WPF? - wpf

i have textbox and progressbar in my usercontrol that place in stackpanel.
i write a Orientation Property but it doesnt work???
if orientation set to horizontal,textbox and progressbar should be place horizontally and if orientation set to vertically,textbox and progressbar should be place Vertically.
my code is :
<StackPanel Orientation="Horizontal">
<TextBox Name="TValue" Width="40" Height="23" TextChanged="TValue_TextChanged"/>
<ProgressBar Name="PG1" Width="200" Height="23"/>
</StackPanel>
and my property is:
//Define Orientation Property
public Orientation Orientation
{
get { return (Orientation)GetValue(OrientationProperty); }
set { SetValue(OrientationProperty, value); }
}
// Using a DependencyProperty as the backing store for Orientation. This enables animation, styling, binding, etc...
public static readonly DependencyProperty OrientationProperty =
DependencyProperty.Register("Orientation", typeof(Orientation), typeof(TPUserControl), new UIPropertyMetadata(Orientation.Horizontal));
if u can help me,u save me from storm,THNX

If I understand your problem correctly, you have:
Created a UserControl (lets call it MyUserControl).
Created a dependency property Orientation for MyUserControl.
Within usercontrol you have a stackpanel and you want to bind the Orientation of this stackpanel with Orientation property of MyUserControl.
Try this:
<StackPanel Orientation="{Binding Orientation,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type MyUserControl }}}">
<TextBox Name="TValue" Width="40" Height="23" TextChanged="TValue_TextChanged"/>
<ProgressBar Name="PG1" Width="200" Height="23"/>
</StackPanel>
Suggestions:
Be more explicit while asking for help. You stated a problem (and that
too not clearly) and then didn't even mention the question. :)
You may want to check if defining a ControlTemplate helps in your scenario.

Related

Modify content of resource

I have a UserControl that contains a TabControl that has an ItemTemplate that in turn has a Button. I want the user be able to change the content of that button, e.g. change it from TextBlock to Image.
A solution I thought of was to set the button's content from the Resources of the UserControl and overwrite the Resource by setting it on the ResourceDictionary of the entailing Window. Of course that does not work as StaticResource always resolves to the "closest" instance it can find.
I then thought of modifying the resource in the constructor of my UserControl, depending on some property. But it seems, one cannot change a resource. Below is a close sample showing the idea with a simple ListBox in a Window in which I try to change "What" to "How".
How would you approach this?
<Window.Resources>
<TextBlock x:Key="key" Text="What: " x:Shared="false" />
</Window.Resources>
<Grid Margin="10">
<ListBox Name="lbTodoList" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StaticResource ResourceKey="key" />
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TextBlock tb = FindResource("key") as TextBlock;
tb.Text = "How: ";
List<string> items = new List<string>();
items.Add("Item 1");
items.Add("Item 2");
items.Add("Item 3");
lbTodoList.ItemsSource = items;
}
}
Instead of trying to override a resource, you should just treat it like any other XAML data-binding templating issue.
Instead of:
<StaticResource ResourceKye="key" />
Do something like this:
<TextBlock Text="{Binding LabelText}" />
In your UserControl set the default value of LabelText to "What:" and then allow the user to override the value. The data binding will take care of the rest.
If you want to have more dynamic content, then use a ContentControl instead and have properties for Content, ContentTemplate, and even ContentTemplateSelector depending on what you need to do.
<ContentControl
Content="{Binding MyContent}"
ContentTemplate="{Binding MyContentTemplate}"
ContentTemplateSelector="{Binding MyContentTemplateSelector}" />
This opens up a lot of flexibility.

RadTabControl reloading content in swiching tabitems

I'm using RadTabControl and I have a problem with reloading tabs. If I add two tabs and edit first tab content and go to the second tab and come back first tab lost the content. If I edit some tab content and click to edited tab title and go to another tab and come back it binds and changes context. I have a lost focus event for textbox(content) if I set break point to lost focus event and after running I test all situation it's good working but I need to change Note.Content property in lost focus by binding Content textbox with content property. Content property is in Note class.
xmlns:ec="clr-namespace:WpfControls;assembly=WpfControls"
<UserControl.Resources>
<DataTemplate x:Key="TabContent">
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<TextBox Text="{Binding Content}" Name="ContentTextBox" MinLines="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" TextWrapping="Wrap" AcceptsReturn="True"/>
</ScrollViewer>
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid Grid.Column="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ec:NoteBook x:Name="uiNotebook" TabContentTemplate="{StaticResource TabContent}" Margin="30" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
public DataTemplate TabContentTemplate
{
get { return (DataTemplate)GetValue(TabContentTemplateProperty); }
set { SetValue(TabContentTemplateProperty, value); }
}
// Using a DependencyProperty as the backing store for ContentTemplate. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TabContentTemplateProperty =
DependencyProperty.Register("TabTemplate", typeof(DataTemplate), typeof(NoteBook), new PropertyMetadata(null));
Can anybody help me? Thanks Jamshed
After long researches I find the answer and I want to share it. it was IsContentPreserved property and I set it to true, it works!
<telerik:RadTabControl x:Name="tabControl" IsContentPreserved="True" ItemsSource="{Binding Tabs}">

Binding OnwayToSource not working as expected - what alternatives?

Ive a business object - call it Fish (not derived from anything ie not a DependancyObject) that is displayed in a ListBox using a DataTemplate. Else where in code I need to know the rendered width of the TextBlock part of the Fish DataTemplate through a reference to a Fish. No problem I thought. I added a width and height properties to Fish class and in my data template I bound the TextBlock width/height to these using Mode=OnwayToSource.
Problem: the Width/Height are always NaN when setting my Fish.width/heigh properties. I tried this workaround:
OneWayToSource Binding seems broken in .NET 4.0
but it doesnt work either (value is always NaN).
I cant bind to ActualWidth/ActualHeight because they are read only (why can't I bind OnwayToSource on a readonly property!!)
What alternatives do I have? Do I have to derive Fish from DependancyObject and make my properties DPs?
XAML:
<DataTemplate DataType="{x:Type p:Fish}">
<Border BorderBrush="Black" BorderThickness="2" >
<TextBlock FontSize="14" TextAlignment="Center" VerticalAlignment="Center"
Width="{Binding Path=width, Mode=OneWayToSource}"
Height="{Binding Path=height, Mode=OneWayToSource}" ...
Code:
class Fish {
public double width { get; set; } // From DataTemplate TextBlock.Width.
public double height { get; set; } // From DataTemplate TextBlock.Height
}
...
double rendered_width = my_fish.width; // Use the rendered width!
I've finally realized what you're trying to do, and you're right that it should work. WPF, however, disagrees. I see that it's a problem that others have had before, but that is apparently by design. You can't set up a binding on a read only property, even if you're just wanting to bind OneWayToSource.
Here is a question with the same problem: OneWayToSource binding from readonly property in XAML Their workaround was to put a container (which has read/write width/height) around the xaml element and set up the binding on that container. This might work for you.
There is an unresolved issue related to this on Microsoft Connect where it is claimed to be behaviour by design: http://connect.microsoft.com/VisualStudio/feedback/details/540833/onewaytosource-binding-from-a-readonly-dependency-property. Someone claims a workaround in the related thread which uses a converter. You can try it, but I'm not sure it'll work in your case, as their binding was to a custom control, not a built in framework element.
Even Better
In This Solution, Boogaart came up with an implementation defining a new attached property (Similar to DockPanel.Dock="Top") which allows any element to provide its width and height for observation:
<TextBlock ...
SizeObserver.Observe="True"
SizeObserver.ObservedWidth="{Binding Width, Mode=OneWayToSource}"
SizeObserver.ObservedHeight="{Binding Height, Mode=OneWayToSource}"
Try it on and see if it fits.
If you consume these properties after some sort of action i.e. a button press or click on a hyperlink, then you can pass in the the ActualWidth and Height via a CommandParameter of a command. Otherwise I would suggest using triggers such as the ones available here:
http://expressionblend.codeplex.com/wikipage?title=Behaviors%20and%20Effects&referringTitle=Documentation
I agree that it appears counter intuitive that OneWayToSource bindings don't work on read only dependency properties.
Try binding OneWay. I think OneWayToSource is means wants to write to the source.
http://msdn.microsoft.com/en-us/library/system.windows.data.bindingmode.aspx
I did a test and sure enough Width = NaN until width is Assigned (set). I understand this is not the behavior you want. Try this. Where the Width is assigned it is reported (as 200). Where the Width is not assigned it is reported as NaN. But ActualWidth IS correct. ActualWidth is there but clearly the way you are trying to get it is not working.
<StackPanel Orientation="Vertical">
<Border BorderThickness="1" BorderBrush="Red">
<TextBlock Name="tbwidthA" Text="{Binding Path=Howdy}" HorizontalAlignment="Left" Width="200"/>
</Border>
<TextBlock Name="tbwidthAw" Text="{Binding ElementName=tbwidthA, Path=Width}" HorizontalAlignment="Left"/>
<TextBlock Name="tbwidthAaw" Text="{Binding ElementName=tbwidthA, Path=ActualWidth}" HorizontalAlignment="Left" />
<Border BorderThickness="1" BorderBrush="Red">
<TextBlock Name="tbwidthB" Text="{Binding Path=Howdy}" HorizontalAlignment="Left" />
</Border>
<TextBlock Name="tbwidthBw" Text="{Binding ElementName=tbwidthB, Path=Width}" HorizontalAlignment="Left" />
<TextBlock Name="tbwidthAbw" Text="{Binding ElementName=tbwidthB, Path=ActualWidth}" HorizontalAlignment="Left" />
<Button Content="TBwidth" Click="Button_Click_1" Width="60" HorizontalAlignment="Left" />
</StackPanel>
What is interesting is the Button does report the correct ActualWidth but Width is NaN.
Debug.WriteLine(tbwidthB.Width.ToString());
Debug.WriteLine(tbwidthB.ActualWidth.ToString());

WPF - How to expose subelements of a UserControl

I have created a XAML UserControl that is used to enter the current date using some up/down controls. The interesting parts of the UserControl are as follows:
<UserControl x:Class="MyApp.Controls.DateEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uControl="clr-namespace:MyApp.Controls"
xmlns:uConverters="clr-namespace:MyApp.Converters"
x:Name="dateEntry">
etc...
Here's where the numeric up/down controls are defined
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<uControl:NumericEntry x:Name="monthEntry" Label="Month" Style="{StaticResource SmallNumericEntry}" Maximum="12" Number="{Binding Path=Month, ElementName=dateEntry, Mode=TwoWay}" Minimum="1"/>
<uControl:NumericEntry x:Name="dayEntry" Label="Day" Style="{StaticResource SmallNumericEntry}" Margin="10,0,0,0" Maximum="31" Number="{Binding ElementName=dateEntry, Path=Day, Mode=TwoWay}" Minimum="1"/>
<uControl:NumericEntry x:Name="yearEntry" Label="Year" Style="{StaticResource LargeNumericEntry}" Margin="10,0,0,0" Maximum="9999" Number="{Binding ElementName=dateEntry, Path=Year, Mode=TwoWay}" Minimum="1"/>
</StackPanel>
You can see how certain properties of the NumericEntries are defined (e.g. For yearEntry, Maximum="9999"). Now what I want to do, is allow any anyone who uses this UserControl in their XAML code to be able to modify this property. Here's some XAML (seperate file) that uses this UserControl:
<uControl:DateEntry
x:Name="treatmentDate"
Date="{Binding Source={StaticResource currentTreatment}, Path=Date, Mode=TwoWay}"
Margin="10" />
I want to override the value of yearEntry.Maximum to be 2099. However, in the XAML file that uses the UserControl, it doesn't have visibility to yearEntry. It is possible to modify this programatically in the .cs file, but this kind of definition surely belongs in the XAML file.
Thanks in advance for your responses!
if your dateEntry class had a dependency property for maximum year, you could bind to them from any control that uses them. then your code to set the year would look like this
<uControl:NumericEntry
x:Name="yearEntry"
Label="Year"
Style="{StaticResource LargeNumericEntry}"
Margin="10,0,0,0"
Maximum="{Binding ElementName=dateEntry, Path=MaximumYear}"
Number="{Binding ElementName=dateEntry, Path=Year, Mode=TwoWay}"
Minimum="1"/>
and in your code behind you could set the max to 9999 in the dependency props definition
public int MaximumYear {
get { return (int)GetValue(MaximumYearProperty); }
set { SetValue(MaximumYearProperty, value); }
}
public static readonly DependencyProperty MaximumYearProperty =
DependencyProperty.Register("MaximumYear", typeof(int), typeof(NumericEntry), new UIPropertyMetadata(9999));
then use it like this
<uControl:DateEntry
x:Name="treatmentDate"
Date="{Binding Source={StaticResource currentTreatment}, Path=Date, Mode=TwoWay}"
MaximumYear="9999"
Margin="10" />
Anything you want to be externally visible on your UserControl generally should be a public property, event, etc, on that UserControl. Except in extremely rare situations clients should not have to drill down into the UserControl's "guts" to work with them.
In your case, you should have a MaximumYear DependencyProperty of type int declared in your UserControl. This is declared in the code-behind - use "wpfdp" template for VB or "propdp" for C# editor. (Type the template abbreviation and hit tab to get a fillable template).
Once your DependencyProperty has been created, your UserControl's XAML can bind to it:
<uControl:NumericEntry x:Name="yearEntry" Maximum="{Binding MaximumYear, ...
and your clients can use it as an ordinary property or in XAML:
dateEntry.MaximumYear = 2010;
or in the client code's XAML:
<uControl:DateEntry MaximumYear="2010" ...

WPF TextBlock Binding to DependencyProperty

I have what I believe to be about one of the most simple cases of attempting to bind a view to a dependencyproperty in the view model. It seems that the initial changes are reflected in the view but other changes to the DP do not update the view's TextBlock. I'm probably just missing something simple but I just can't see what it is. Please take a look...
My XAML has a status bar on the bottom of the window. I want to bind to the DP "VRAStatus".
<StatusBar x:Name="sbar" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2"
VerticalAlignment="Bottom" Background="LightBlue" Opacity="0.4" DockPanel.Dock="Bottom" >
<StatusBarItem>
<TextBlock x:Name="statusBar" Text="{Binding VRAStatus}" />
</StatusBarItem>
<StatusBarItem>
<Separator Style="{StaticResource StatusBarSeparatorStyle}"/>
</StatusBarItem>
</StatusBar>
My viewmodel has the DP defined:
public string VRAStatus
{
get { return (string)GetValue(VRAStatusProperty); }
set { SetValue(VRAStatusProperty, value); }
}
// Using a DependencyProperty as the backing store for VRAStatus.
public static readonly DependencyProperty VRAStatusProperty =
DependencyProperty.Register("VRAStatus", typeof(string), typeof(PenskeRouteAssistViewModel),new PropertyMetadata(string.Empty));
Then, in my code I set the DP:
VRAStatus = "Test Message...";
Is there something obvious here that I am missing? In my constructor for the viewmodel I set the DP like this:
VRAStatus = "Ready";
I never get the Test Message to display.
You need to add DataContext="{Binding RelativeSource={RelativeSource Self}} in .
As it turns out things were a little more complicated than I had thought (like, when is that NOT the case :) My RibbonControl was in a UserControl to get all of that XAML out of the MainWindow. It was the fact that it was in a UserControl that made it work differently with the ViewModel. I don't know why - probably one of those mysteries that won't ever be solved. But by putting my RibbonControl directly on the MainWindow, everything works as expected - both with a DP and a C# Property. Interesting. (Wish I could get back those two days of my life!)
thanks,
Bill
Try specifying the name of the DP with the Path flag in the binding like this:
<TextBlock x:Name="statusBar" Text="{Binding Path=VRAStatus}">
Bill,
When and where do you set the DataContext? I had problems in the past that when I set the DataContext before the InitializeComponent, my Bindings never executed properly.
Also, for curiosity's sake: why do you use a DP in your ViewModel instead of just a Property?
Try to specify the UpdateSourceTrigger property of the Binding:
<StatusBar x:Name="sbar" Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2"
VerticalAlignment="Bottom" Background="LightBlue" Opacity="0.4" DockPanel.Dock="Bottom" >
<StatusBarItem>
<TextBlock x:Name="statusBar" Text="{Binding VRAStatus, UpdateSourceTrigger=PropertyChanged}" />
</StatusBarItem>
<StatusBarItem>
<Separator Style="{StaticResource StatusBarSeparatorStyle}"/>
</StatusBarItem>
</StatusBar>

Resources