Is there a possibility to prevent a Expander control in WPF to collapse, when certain conditions are given. For my usecase it is not possible to do it directly in the xaml, because whether the Expander can be collapsed or not depends on condition just known during run time.
Its no option for me to use an event, because the project is a test project to seperate gui and code strictly.
Perhaps you can bind to the IsExpanded property.
For example you can use a DataTrigger, MultiDataTrigger, ValueConverter, or MultiValueConverter to manage the data binding to the IsExpanded property.
There's also a interesting article here that may help you.
If you want to set the Expander to always remain toggle-on. Just leaving it here.
<Expander IsExpanded="True"></Expander>
Related
I was trying to get the text that I wrote in a DataGrid cell after editing it, so I put a breakpoint in the function CellEditEnding and looked at the EventArgs and noticed that it contains the property "Text", so I wouldn't have to do the usual XAML binding hacks to get it.
However, I quickly noticed that it will not let me access it.
After taking a look at the FrameworkElement class, I can confirm that there is no Text property, so what is going on, why can't I acces the property?
why can't I acces the property?
Because a FrameworkElement indeed has no Text property.
TextBox, which derives from FrameworkElement, has a Text property though so you could cast the EditingElement to a TextBox and then access the property:
string text = (e.EditingElement as TextBox)?.Text;
Visual Studio displays the properties of the actual object in memory.
It's a bad idea to use the UI as a data store and try and directly work with it.
You should bind an observablecollection of t to the itemssource of your datagrid and work with each instance of t.
That will be far easier to work with.
As to why are some properties inaccessible?
It's because those properties aren't where you think they are. The DatagridCell has a series of things nested within it.
DataGridCell > Border > ContentPresenter > TextBlock
Download snoop https://github.com/snoopwpf/snoopwpf or install using chocolatey / your preferred method.
Run snoop.
Run your app.
Drag the right gunsight thing over you window.
A window should open up with two panels. Controls and properties.
Mouse over a datagrid cell.
press shift+ctrl and you should see the element under the mouse selected in the ui tree.
A datagrid is pretty complicated and there are multiple things in each row.
See that textblock there?
That's the thing has a text property.
Or at least that's the thing when you're not in edit mode.
Switch to edit mode and I have a TextBoxView.
So one complication is, which are you working with at a given time?
i'm using an ItemsControl to generate a list of controls based on my model.
When looking at the visual tree, i noticed that each of the rendered control is wrapped in a ContentPresenter. The controls that are added are a 3rd party control and are designed to display a splitter between each control if they are siblings..this allows a user to size each control. For example the following will show a splitter between each of the controls at run time.
<StackPanel>
<3rdPartyControl />
<3rdPartyControl />
<3rdPartyControl />
</StackPanel>
When using an ItemsControl, each of the 3rdPartyControl are wrapped in a ContentPresenter, and thus no splitter is shown. I have tried various ways to try and solve this problem but unable to get this to work unless i write code behind to add each control rather than rely on Xaml.
Does anyone know of a way to replace the contentpresenter completely (in my case with 3rdpartyControl)?
Thanks
In order to replace the ContentPresenter you could derive from ItemsControl and override the GetContainerForItemOverride method to create a specialized container control.
ListBox for example overrides this method to create a ListBoxItem as container for a new item object.
That's true, every element that you add to ItemsControl is wrapped with ContentPresenter, you can find more details about it in the greate series of articles from dr.wpf ItemsControl a-z
One way I would suggest to try is to change ItemsControl to ListBox and make ListBox act like ItemsControl. In this case you can re-style/re-template ListBoxItem and replace ContentPresenter with your control. You would also need to stop selection support. Here is ListBox style that you need to change.
I would like to, based on state, display one or the other control assigned to a grid's cell, such as:
<Button x:Name="btnBla" Grid.Row=42 Grid.Column=7></Button>
<TextBlock x:Name="txtblockOh" Grid.Row=42 Grid.Column=7 IsEnabled="false"></TextBlock>
...and then in the code-behind:
btnBla.IsEnabled = someBool;
txtblockOh.IsEnabled = ! btnBla.IsEnabled;
Is this the preferred method to accomplish this?
if you want to "Show" one at a time as your question states, you should change the Visibility property insted of the IsEnabled.
You CAN do it in code, although I always recommend against manipulating UI elements in code (be it WPF, Silverlight or WinRT), all XAML-based technologies are much friendlier if you use the MVVM way of thinking.
Yo can be look at this page: Visibility
In a DataTemplate I want to show the Control which is actually replaced by the DataTemplate. With error validation, this is possible by using <AdornedElementPlaceHolder />. However, this seems not to work in a normal DataTemplate.
I think there would be a simple solution, but just can't find it.
Thanks a lot
This is not possible and here is why. DataTemplate doesn't replace anything. Instead, a control that defines a DataTemplate contains the content provided by it. If it was possible then there would be an infinite loop (control -> data template -> control -> data template -> ...).
I suggest you read the following article to fully understand data templates: http://msdn.microsoft.com/en-us/library/ms742521.aspx
A DataTemplate in some sense "replaces" a data object and not a UI object - in other words, not a Control. If you are trying to work with properties of the Control (usually either a ContentControl or ItemsControl) that is using the template, try a RelativeSource Binding where the AncestorType is the type of the Control.
I'm fairly new to WPF and I have this scenario:
I have an application that contains an area where different sets of controls should be displayed at different time(different application states).
I'm wondering what is the approach in WPF?
In winforms I would make controls visible/invisible at runtime. If there were too many controls I would group them on Panels/UserControls and show/hide those.
My gut tells me there is a better way in WPF.
There are lots of options for doing this in WPF. In addition to hiding and showing individual or groups of controls by setting Visibility, you could use different DataTemplates to contain the set of controls for each state and switch between those. All you need is a ContentControl on which you can set the ContentTemplate. The ContentTemplate value can then be switched to different DataTemplates using a Trigger, a Binding, from code, or by using ContentTemplateSelector to choose a template.
The Visibility property describes your old winforms habits perfectly.
You'll also want to look into Visual States. This will allow you to hide/show multiple controls and even change other properties (i.e. enable state, font color).