Set value of x:Uid programmatically - c#

I am creating an AppBarButton in code behind file of XAML view.
Currently, I have AppBarButton defined in XAML as below:
<AppBarButton x:Name="SelectVisitAppBarButton" x:Uid="AppBar_TransferVisit" Margin="0,0,12,0" Icon="Bullets" Style="{StaticResource TransferAppBarButtonStyle}" IsEnabled="{Binding ScheduleViewVm.IsVisitSelectionEnable}" Click="SelectVisit_Click" />
I want to convert this XAML into C# code. Following is the code that I have till now.
AppBarButton SelectVisitAppBarButton = new AppBarButton();
SelectVisitAppBarButton.Margin = new Thickness(0, 0, 12, 0);
SymbolIcon bulletSymbol = new SymbolIcon();
bulletSymbol.Symbol = Symbol.Bullets;
SelectVisitAppBarButton.Icon = bulletSymbol;
SelectVisitAppBarButton.Style = App.Current.Resources["TransferAppBarButtonStyle"] as Style;
SelectVisitAppBarButton.Click += SelectVisit_Click;
Binding b = new Binding();
b.Source = _viewModel.ScheduleViewVm.IsVisitSelectionEnable;
SelectVisitAppBarButton.SetBinding(Control.IsEnabledProperty, b);
Appbar.Children.Add(SelectVisitAppBarButton);
The only thing I am looking for is to convert x:Uid="AppBar_TransferVisit" into its equivalent C# code. Any help on this is highly appreciated.
Thanks,
Naresh Ravlani.

It seems that you cannot actually set the x:Uid attribute programmatically in UWP:
How to set control x:Uid attribute programmatically for a metro app control?
This is because it's a XAML directive rather than a property:
Doing localization in visualstatemanager by changing x:uid?
You will have to set the corresponding properties of the AppBarButton directly, e.g.:
AppBarButton SelectVisitAppBarButton = new AppBarButton();
var resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();
var text = resourceLoader.GetString("SomeResource");
AppBarButton SelectVisitAppBarButton = new AppBarButton();
SelectVisitAppBarButton.Content = text;

I can confirm that I have spoken to the UWP-XAML platform team about programatically accessing x:UID and it is not possible. This is a shortcoming, if you ask me. But it is what it is at this time. :)

There's a workaround, using XamlReader to load the button from xaml.
Button btn = (Button)XamlReader.Load("<Button xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' x:Uid='btnSubmit' Margin='5,0,0,0'/>");
btn.OtherProperty = xxxx

Related

C# Data Binding via code behind doesn't work for Text property in TextBox

I have a textbox with xaml markup like this:
<TextBox x:Name="txtHN" Text="{Binding Path=AN}"/>
The above code works perfectly well. But when i change the data binding implementation from XAML to code-behind, It does not work anymore. The following code-behind does not work anymore:
Binding textHnBinding = new Binding();
textHnBinding.Path = new PropertyPath("AN");
txtHN.SetBinding(TextBox.TextProperty, textHnBinding);
I had set the textbox.datacontext to the same collectionviewsource but the code-behind version does not work anymore. I had really no idea what seems to be the culprit.
I use the following code for the CVS.source:
IEnumerable<decimal> ANListWard4 = (from s in context.IPDAN
where ward.Contains(s.CURRENTWARD)
select s.AN).Distinct().OrderBy(n => n);
List<IPDAN> Ward4AN = new List<IPDAN>();
foreach (decimal d in ANListWard4)
{
IPDAN ward4AN1 = new IPDAN();
ward4AN1.AN = d;
Ward4AN.Add(ward4AN1);
}
I set the CVS.Source to Ward4AN. There was no instance where the Ward4AN was null, or has no data.
Check whether the collectionViewSource is not null when you are doing the binding.If the object is null when you are adding the binding, the binding might not work.
Also check whether in loaded event it works or not.
Can you try :
Binding textHnBinding = new Binding("AN");
txtHN.SetBinding(TextBox.TextProperty, textHnBinding);
This is how I done all my binding so I think it should work.
EDIT :
Long time no uses binding so my apologies if I'm wrong again :
Binding textHnBinding = new Binding("AN");
FrameworkElementFactory textHN = new FrameworkElementFactory(typeof(TextBox));
txtHN.SetBinding(TextBox.TextProperty, textHnBinding);
Can you try instantiate your Control like this instead of in Xaml to check if it will work (as me) ? Thank you.

wpf dynamic border thickness binding

I have a border generated dynamically.
I want to bind thickness property of it, with my style model.
Border db = new Border();
Binding borderthickness = new Binding();
borderthickness.Source = this.imodel.GridStyleProperties.BorderThickness;
borderthickness.Path = new PropertyPath("BorderThickness");
BindingOperations.SetBinding(db, Border.BorderThicknessProperty, borderthickness);
This is what I have done so far. Its not working for me.
Please suggest me what is wrong with this code.
Thank you
You are binding to a BorderThickness object, with Path set to BorderThickness. That means the binding will look in this.imodel.GridStyleProperties.BorderThickness.BorderThickness which doesn't exist.
Try
borderthickness.Source = this.imodel.GridStyleProperties;
borderthickness.Path = new PropertyPath("BorderThickness");
or just
borderthickness.Source = this.imodel.GridStyleProperties.BorderThickness;

Setting the Datacontext of a dynamically created control

I have a UserControl (Map) that contains a Canvas control. I am dynamically adding a control (Gate) to this canvas from the code behind.
I want the Gate objects DataContext to be the "Gate" property of the Map's DataContext. This is being done in the code behind.
Binding dataContextBinding = new Binding();
dataContextBinding.RelativeSource = new RelativeSource(RelativeSourceMode.Self);
dataContextBinding.Path = new PropertyPath("DataContext.SelectedLevelModule.Gate");
dataContextBinding.Mode = BindingMode.TwoWay;
dataContextBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(gate, DataContextProperty, dataContextBinding);
After this block of code runs, the gate.DateContext is null...
Any ways this can be done? Drawing a blank..
Thanks
Harold
You are setting the property path to DataContext.SelectedLevelModule.Gate. You are then assigning the binding to the DataContextProperty. I think what is happening is that the path is now gate.DataContext.DataContext.SelectedLevelModule.Gate.
Try removing DataContext from your PropertyPath and see if that fixes it. You are already assigning it to the DataContext, you should not have to specify it in the Path.
var dataContextBinding = new Binding();
dataContextBinding.Path = new PropertyPath("SelectedLevelModule.Gate");
BindingOperations.SetBinding(gate, DataContextProperty, dataContextBinding);

How can I bind to the property of a class from the codebehind?

In my XAML I have this:
<TextBlock Text="{Binding Stats.Scores.Team}" Style="{StaticResource Column_Value_Large}" />
I need to be able to create that TextBlock, in it's entirety, in the codebehind. Here's what I have:
foreach (var Stats in player){
var columnHeaderScore = new TextBlock
{
Style = Application.Current.Resources["Column_Value_Large"] as Style,
};
columnHeaderScore.SetBinding(TextBlock.TextProperty, new Binding
{
Path = new PropertyPath("Stats.Scores.Team"),
});
columnHeaderStackPanel.Children.Add(columnHeaderScore);
}
However, the binding doesn't seem to be working. What's the appropriate way to set the binding in the codebehind?
Edit for context: my goal is to generate a bunch of these text boxes inside a big loop in the codebehind. See my revised example above which now shows the loop. Since I want to do it this way, I don't think there's any possible way for me to do it in the XAML; I would have to set the binding in the codebehind.
I think you use xaml in a wrong way. Why dont you set theTextBlockin the XAML code and bind itsVisibilityto a property or use aStyle. Then you dont have to create the binding in the codebehind.
EDIT: Why don't you use a ItemPanel or something like that to which you bind your collection and give it a DataTemplate which displays the TextBoxes?
I got it.
My problem was using "Path" in SetBinding instead of "Source". The working code looks like this:
foreach (var Stats in player){
var columnHeaderScore = new TextBlock
{
Style = Application.Current.Resources["Column_Value_Large"] as Style,
};
columnHeaderScore.SetBinding(TextBlock.TextProperty, new Binding
{
Source = Stats.Scores.Team,
});
columnHeaderStackPanel.Children.Add(columnHeaderScore);
}

How To Create A Bottom Or Top AppBar in Windows Store App Using C#?

I'm aware of the way to create the AppBar via XAML code. I want to know how to create the AppBar via C#.
On the Windows Phone App, i can just do this.
ApplicationBar = new ApplicationBar(){
Mode = ApplicationBarMode.Minimized
};
ApplicationBarMenuItem copyLinkButton = new ApplicationBarMenuItem();
copyLinkButton.Click += (sender, e) => { //action };
copyLinkButton.Text = "copy to clipboard";
ApplicationBar.MenuItems.Add(copyLinkButton);
ApplicationBarMenuItem openInIEButton = new ApplicationBarMenuItem();
openInIEButton.Click += (sender, e) => { //action };
openInIEButton.Text = "open in internet explorer";
ApplicationBar.MenuItems.Add(openInIEButton);
How do i do it in Windows Store App?
Update
Thank you #kimsk for giving me an answer to my previous question. I've solved it with your answer. But after solving that problem, another similar problem surfaced.
Because i didn't simply use a button like this,
<Button>Button 3</Button>
I have problem tapping into the Microsoft's default style. Is there anyway to reference to that particular style or do i have to create one from scratch by myself?
<Button Style="{StaticResource EditAppBarButtonStyle}"/>
Thanks again!
It's pretty straightforward if you think about XAML is just a declarative way to create objects of UIElement elements such as AppBar, Button, StackPanel, and so on.
Here is the code to create a BottomAppBar in XAML that you already know:
<Page.BottomAppBar>
<AppBar>
<StackPanel Orientation="Horizontal">
<Button>Button 3</Button>
<Button>Button 4</Button>
</StackPanel>
</AppBar>
</Page.BottomAppBar>
Here is the C# code that creates a TopAppBar:
var appBar = new AppBar();
var stackPanel = new StackPanel{Orientation = Orientation.Horizontal};
stackPanel.Children.Add(new Button { Content = "Button1" });
stackPanel.Children.Add(new Button { Content = "Button2" });
var buttonWithStyle = new Button();
buttonWithStyle.Style = Application.Current.Resources["EditAppBarButtonStyle"] as Style;
stackPanel.Children.Add(buttonWithStyle);
appBar.Content = stackPanel;
this.TopAppBar = appBar;
Notice the pattern? :-)
And this is the screenshot:
Hope this helps!

Categories