I made an application in WPF (.Net 4.7). For code protection, I am using .Net Reactor.
I am using following syntax to bind textblock to first element of list in my model.
<TextBlock Text="{Binding list[0].property1}"/>
This code works fine but after obfuscation, this code no longer works. I changed it to this
<WrapPanel DataContext="{Binding Path=list}">
<TextBlock Text="{Binding property1}"/>
</WrapPanel>
and this bind textblock to 'property1' of list first element (what I needed). I accidentally got this solution, I don't know if it is a proper way or not. I build application without obfuscation and above also works. Questions I have regarding this are
Why binding is not working like usual after obfuscation?
Using this method, does it always bind to first element of collection? If it always bind to first element, than I will continue deployment of application without wasting more time.
Sorry for bad English!!
Scenario: Developing a "thick" client in UWP, using c# destined for the desktop of Windows 8.1/10 (a store app).
In my user interface, I tried to use the following inline
<StackPanel Grid.Column="0">
<TextBlock x:Name="Qty_Size_Crust" Margin="25,10,20,0" Padding="0,0,0,0" TextAlignment="Left" TextWrapping="Wrap" MaxHeight="25" Foreground="#ff230909" FontFamily="Segoe UI" FontSize="16" xml:space="preserve" HorizontalAlignment="Left">
if ({Binding WidgetName} == "Backend")
{
<Run Text="{Binding ItemCode, Converter=ItemCodeToDescriptionConverter}"/>
}
else
{
<Run Text="See Administrator}"/>
}
</TextBlock>
The compiler would accept this, but during execution, I would neither see Item Description nor See Administrator. Is there something else I should be doing in order for this work? I was able to work around this by putting the code in the ViewModel, but wondered why this didn't work (or maybe it shouldn't).
XAML doesn't work with inline scripts so the answer is simply - it's not supported.
In your example - the condition code is simply added as text runs in the TextBlock, so the compiler accepts that.
As for the best solution to your specific problem - a condition in the view model is a good one. A TemplateSelector would work on the view side, but requires more code. View model might actually also be the best place to put it if you want to be able to test it, so it really is the right way to do it. Putting logic in the view layer would simply add code that can't be unit-tested.
I'm really stumped on how to go about binding fonts to a textbox. I'd like for my user to be able to choose between 3-4 different fonts. I have something like this right now:
<TextBox x:Name="MyTextBox" AcceptsReturn="True" FontSize="20"
FontFamily="{Binding FontSelection}" />
But I have no clue how the c# should look, and I had no luck googling for it. What is the best way to do this? Do I have to create an observable collection? I've tried adding fonts to the Application.Resources, but it wouldn't let me.
Thanks for any answers!
This FontSelection property has to be single item. You could first try simple valid string (like 'Arial'), it could work. Another approach is FontFamily type as poined out by Romasz.
Also there are Converters available, quite easy to implement. http://channel9.msdn.com/Series/Windows-Phone-8-1-Development-for-Absolute-Beginners/Part-25-Advanced-Binding-with-Value-Converters With this you could save user font selection as simple number for example and convert it to appropriate type with Converter.
I'm developing an application using C# and XAML and I've encountered a problem that is confusing me. I have a property in my data called GroupImage and have used binding to set the Source property of an Image with it. That worked fine but when I wanted to do the same thing a second time it doesn't show the image in the second Image control.
<Image Source="{Binding Group.GroupImage}" Width="250" Height="500" Stretch="UniformToFill" />
<Image VerticalAlignment="Bottom" Stretch="UniformToFill" Source="{Binding Group.GroupImage}" Grid.RowSpan="2"/>
The top one works fine the bottom one doesn't. I have been reading about Data Binding and have gotten the impression that you need to specify something in the DataContext to use a property more than once. Is this right? It seems a very strange way of doing this.
I am relatively new to C# so sorry if I'm missing something obvious. I'd appreciate a more knowledgeable cluing me in.
Thanks
Update Following the assistance I received I figured out that the context was being set to
DataContext="{Binding Group}"
And as a result my second line needed to change to the following since the Data Context was already set to Group.
<Image VerticalAlignment="Bottom" Stretch="UniformToFill" Source="{Binding GroupImage}" Grid.RowSpan="2"/>
You don't need to specify something in the DataContext to use a property more than once. But your two Image have to have the right DataContext (you can easily test it with the debugger), depending on their location on the visual tree (You didn't provide any code for the DataContext part ?) .
You can also check that your Image's Width/Height are not 0.
I'm trying to databind a Run of a TextBlock in code at runtime, and I can't for the life of me figure out how.
Several sources on the internet suggest this isn't possible without some (not too pretty) additional workarounds, and, more importantly, it should completely fail when you try to do it in XAML.
Yet, in my application I have the following, which works beautifully:
<DataTemplate x:Key="PitchTemplate">
<Grid Width="120" Height="120" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock HorizontalAlignment="Center"
VerticalAlignment="Center"
TextAlignment="Center">
<Run Text="{Binding}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" FontSize="36"/>
<LineBreak/>
<Run Text="{Binding Frequency, StringFormat=\{0:n2\}Hz}" FontFamily="{StaticResource PhoneFontFamilyNormal}" Foreground="{StaticResource PhoneSubtleBrush}"/>
</TextBlock>
</Grid>
</DataTemplate>
So I figured: If it can be done in XAML, it should be possible to do it in code.
Sofar, to no avail. Using the "regular" way of binding in code won't work; the Run class doesn't inherit from FrameworkElement, so doesn't have a SetBinding method, and it's Text property is not a DependencyProperty.
Using BindingOperations.SetBinding doesn't work because the Text property is not a DependencyProperty.
I'm up to the point that I'm willing to accept that it can't be done at runtime (although not without a last attempt at StackOverflow), but I'm still curious if
This can be done in code at runtime?
And if not:
How come it does work in XAML?
EDIT:
The example shown is just there to show that it can be done in XAML. The reason I need to create the bindings in code, is that I have a control that dynamically creates other elements, which need to be data bound.
UPDATE:
As Pete and I both found out, there is a dependency property for Text, but it's private. I assume that's why it does work through XAML (the xaml parser probably has more rights when it comes to reflection, and more knowledge in general about classes).
The upside is, that this means (tried & tested) it also works through XamlReader.Load(), which is (sofar) the cleanest solution I've come up with.
But if anyone has anything better, I'd be glad to hear about it.
Run.Text is backed by the private TextProperty which means you can't directly set its value without some reflection gimmicks, something like this:
Run r=new Run();
r.Text = "Moo";
var field=r.GetType().GetField("TextProperty", BindingFlags.Static | BindingFlags.NonPublic);
var dp=field.GetValue(null) as DependencyProperty;
BindingOperations.SetBinding(r, dp, new Binding {...});
This is rather ugly, but perhaps it can be useful.
You can find various workarounds for this. This SO post uses a custom attached property to configure binding. The attached property is used because Run is a sealed class in Silverlight so you can't create you own Run that supports binding.
The reason that it works in XAML but not in code-behind might be that there is a dependency property for Text, but it is private. It's a little bit 'black magic' to me though, so that's just a guess! This is a strange one, as in WPF the Run does inherit from FrameworkContentElement and has a SetBinding method...
Could you create a subclass of Run that contains a public DependencyProperty for text? I'm afraid I don't have the Silverlight dev tools to hand to try it out at the moment, but I'll try and take a look later.
Thanks both to Pete & Panagiotis for their efforts and suggestions (both 1 up).
In the end, I decided to go with my own solution (found in the "Update" section of the question): Create dedicated XAML strings containing the Run including the binding, and use XamlReader.Load() to parse it, and return a Run object.
The situation I'm working on is quite specific, so a local solution to the problem is good enough (for now). Reflection, as suggested by Panagiotis, won't work due to restrictions imposed by Silverlight. Lastly, the BindableRuns solutions would need either extensive work to deal with nested properties, or I would have to "uglify" my view model, so I discarded it (also for now).
Thanks all for your input.