Make combobox unselectable? or better UI?
This may seem strange... but I'm wondering if there is anyway to make a combobox non selectable. So it displays as normal, except cannot be selected. I have 3 buttons underneath it, Edit, Cancel, Save. (Cancel + save obviously not enabled) The plan is so when user hits edit, they can change the items in the combo box.
I know .IsEnabled
will do this, except it greys the control and makes it hard to read.
Will try to explain further the situation. I have two lists with related items. For example, (I know this doesn't quite work, but imagine as if car manufacturers could buy other manufacturers cars and then have them become theirs) Car manufacturer column, and car type.
So we have (in 2 separate listboxes)
Holden -> Commodore
Holden -> Astra
Ford -> Falcon
Now when one is selected, I programatically make its related partner selected, and then display both items in two Combo boxes. The combo box for manufacturer contains all the manufacturers and the box for the type contains all the different car types, so i开发者_Python百科f e.g. Ford buys the Astra, I select Holden -> Astra, then click edit in the next view, change the manufacturer type combo to Ford then click save.
So the relationship is, a car can only have one car manufacturer, but a car manufacturer can have many cars. I want to be able to a) show the relationships b) edit the relationships and c) (but not so important) add new relationships if cars are added (this happens in a different screen however, don't worry about it)
User can add and delete companies and cars. A car can exist without a company and likewise with a manufacturer. Don't worry too much about the deleting implications here, just say the list stays the same.
Bad example but easier to explain than what I'm actually doing...
Maybe someone has a better idea how to set that up but at the end of the day still wondering if I can make the combobox like I want?
IsEnabled=false
makes it too unreadable.
IsReadOnly=true
makes the text uneditable.
You can make any control, including <ComboBox>
non-focusable and non-clickable by setting these two properties:
<ComboBox Focusable="false" IsHitTestVisible="false" />
This usually does the trick. The control is visually unchanged but you can't interact with it using the mouse, keyboard, or stylus.
(Another option is to use a VisualBrush
and secretly replace the ComboBox
with a picture of it, but that is probably overkill for this situation.)
Update
As Tony points out, it is bad UI design to have a control that looks clickable but isn't. You can avoid this by changing the ComboBox template when IsHitTestVisible="false". Just add something like this to your ComboBox style:
<Style.Triggers>
<Trigger Property="IsHitTestVisible" Value="False">
<Setter Property="Template"
Value="{StaticResource NonClickablComboBoxTemplate}" />
</Trigger>
</Style.Triggers>
This also requires you to define a ControlTemplate
with resource key NonClickableComboBoxTemplate
that provides the look for the non-clicable ComboBox.
Assuming a few things while I wait (or actually not wait) for answers to my comments above, I suggest:
A single listbox, with 2 columns. Car Type on the left, since it cannot be duplicated in the list, and thus is in some way more in 'control' of the relationship:
Type Company -------+----------- Falcon Ford Astra Holden Comm... Holden
Clicking on a particular Company brings up a drop-down of the possible companies for a given car. ie clicking on 'Ford' in the first line (for Falcon) shows a drop-down list of
Ford Holden Toyota
User selects the one they want then off you go. (This does mean you can make all cars owned by the same company, thus some companies may have no cars. If that is a problem, you could probably check and put up a message box 'Every company needs at least one car' etc.)
By selecting the headings (Type or Company) you can sort the lists. Thus seeing all Holden cars ordered together, etc.
Note that you CANNOT click on an entry in the Type column - ie you can't change line 2 from 'Astra' to 'Comm'. This is probably good because that makes it impossible to have the same pairing listed twice.
If your real example really implies Company -> Car 'order' then you could switch the order of the columns. But typically the uneditable 'controlling' column is on the left. (Because we read left-to-right. In areas that have right-to-left languages you should switch to order of everything - OK/Cancel, etc.)
How about when you don't want the combobox to be editable, you handle the Enter
event by putting focus elsewhere. Without testing it, you might need to do the same with the Click
event (not sure off-hand if a click fires Enter
).
That way the text remains visible, but the user cannot edit the text or selection.
After the user clicks the Edit button, disable the handler(s).
If you simply want to make your combo box disabled but easier to read then just modify a copy of the template.
In Blend...
Object --> Edit Template --> Edit a Copy...
Then find the section for the disabled state and change it to look how you like.
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="DisabledVisualElement" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value=".55"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Then set the Opacity to something like 0.9
Hey, u'r using wpf! Simple and accurate solution : Just edit your ComboBox template in blend and remove Trigger for IsEnabled
Here's how:
- Right click your combobox in blend
- Select Edit Template > Edit a Copy
- Give whatever name you like to your style. I chose "ComboBoxStyle1". Define this style in most appropriate place. I've defined it in "This document > Window"
- Now go to "View > Active Document View > XAML view" from menu bar.
- Now go to section
<Style x:Key="ComboBoxStyle1" TargetType="{x:Type ComboBox}">
..............
</Style>
- Within this section, search for and delete following section
<Trigger Property="IsEnabled" Value="false">
..............
</Trigger>
- Save. And aal izz well..!
精彩评论