How to enable/disable checkbox on CGridCtrl in MFC - visual-c++

I am using MFC Grid control 2.27 (http://www.codeproject.com/Articles/8/MFC-Grid-control-2-27) in my project. I would like to enable/disable checkbox on CGridCtrl. I'm not able to find the direct method to disable the check box. In fact, when I write the following line, it disables the grid cell on which checkbox is shown, while checkbox remains enabled.
m_Grid2.GetCell(row,col)->SetState(GVIS_READONLY);
Please suggest any way to disable/enable both checkbox and grid cell at runtime.

My suggestion is to add a second image list to the control. This image list would have disabled (greyed) versions of your images.
In CGridCtrl header you add:
void SetDisabledImageList(CImageList* pList) { m_pDisabledImageList = pList; }
CImageList* GetDisabledImageList() const { return m_pDisabledImageList; }
And add the variable, just after the existing m_pImageList:
CImageList* m_pDisabledImageList;
Now you need to prepare yourself a disabled version of your images and populate a CImageList (beyond the scope of this answer - just need a greyscale version of your image resource). Then, you simply pass that image list in using the new SetDisabledImageList method.
Finally, you modify the CGridCellBase::Draw method and massage the code like this:
CImageList *pImageListToUse = nullptr;
if (!pGrid->IsWindowEnabled())
pImageListToUse = pGrid->GetDisabledImageList();
if(pImageListToUse == nullptr)
pImageListToUse = pGrid->GetImageList();
So, whenever you set the cell as read only, as in your original code, it will render the icon using the disabled image list icons.
The above works OK for me.

Related

How to fix UICollectionView - All cells disappear - Xamarin ios

I am using a UICollectionView in C# Xamarin ios and sometimes all of the cells will disappear from the screen. This happens normally on a scroll and I have to re-invoke the view that my UICollection View is on.
I can't show my exact code as this is a project that I am working on but the initialization basics look a little like this:
Bounds screenBounds = screen.Bounds
UICollectionViewFlowLayout layout = new UICollectionViewFlowLayout();
UICollectionView collectionView = new UICollectionView(layout, bounds)
I initialize a few other things like source and register cell and also add separation and border styles.
I have been also getting an error about a view not being in the hierarchy don't know if this has anything to do with it.
I do return the collectionView at the end and will add this returned value to my template which has a scroll view in which I add the UICollectionView to.
May I also mention I don't use any of the StoryBoard and am using a DuqueReusable cell in my collection view source.
I have been stuck on this for ages so thank you in advance for anyone who can give me any sort of tips or answers to this question.
Insure you make any changes to ItemsSource or to cells data on UI thread only, otherwise you might obtains an uncatchanble async crash and you'll end up with an empty view.
Device.BeginInvokeOnMainThread(() => {
// do your stuff
});

UILabel not wrapping in UITableView until device rotate (iOS8)

I have a custom MvxTableViewCell that is associated with an MvxStandardTableViewSource. That Source is then applied to a UITableView. The custom table cell is defined without any Storyboard or NIB. It is laid out in code and uses AutoLayout.
this.searchResultsTable = new UITableView();
this.searchResultsTable.AccessibilityIdentifier = "SearchView_SearchResultsTable";
this.searchResultsTable.TranslatesAutoresizingMaskIntoConstraints = false;
this.searchResultsTable.RowHeight = UITableView.AutomaticDimension;
this.searchResultsTable.EstimatedRowHeight = 44.0f;
this.searchResultsTable.RegisterClassForCellReuse(typeof(CustomerItemCell), new NSString("CustomerItemCell"));
this.searchResultsTable.AllowsMultipleSelectionDuringEditing = true;
this.searchResultsTable.TableFooterView = new UIView();
this.searchResultsTableDataSource = new MvxStandardTableViewSource(this.searchResultsTable, new NSString("CustomerItemCell"));
this.searchResultsTable.Source = this.searchResultsTableDataSource;
The MVxStandardTableViewSource is databound to a ViewModel property of type List
var set = this.CreateBindingSet<SearchView, SearchViewModel>();
set.Bind(this.searchResultsTableDataSource).To(vm => vm.SearchResults);
set.Bind(this.searchBar).For(x => x.Text).To(vm => vm.CurrentSearchCriteria);
set.Apply();
This all works fine until an item in the data source causes some text wrapping in one of the UILabels and consequently a different height to the other cells.
The cell height is mostly correctly calculated but the UILabel within the
cell does not get redrawn until the device is rotated. I am using iOS AutoLayout to layout the various UIViews in the Cell.
Here are some examples of the large cell in my layout, see the
person "THISISAPATIENTWITHA-" (note this is test data not real people's data)
Initial display of cells
Same cells but device has been rotated
Still the same cells with device rotated back to original
How do I get the UILabel to redraw? We only need to support iOS8 and above.
I cannot see an event or method that gets called when the data binding has happened that would allow me to effectively tell the custom cell "You now have your subviews populated with bound data so redraw them"
The table has another issue too that is covered by this question, Implementing cell reuse for varying height cells in UITableView
Simple Repro on Github
https://github.com/munkii/TableCellResizeIssue
UPDATE:
I've forked your GitHub project and submitted a pull request. But here's my updates to your project.
https://github.com/SharpMobileCode/TableCellResizeIssue
First, you're using FluentLayout for your constraints. Nothing wrong with that actually, but that's some good info to tell others. :)
Second, in order for UITableView.AutomaticDimension to work on TableView Cells, there must be enough autolayout constraints defined in order for the cell to calculate the height of the cell. UITableView.AutomaticDimension depends on proper AutoLayout constraints.
Since you were using FluentLayout to abstract iOS AutoLayout constraints, this was not obvious as no warnings were present in the application output window. Though FluentLayout was technically correct, it however wasn't enough for UITableView.AutomaticDimension to automatically calculate each cell height.
So what I did was added a few more constraints. Look in CustomerItemCell.CreateView() in the pull request (or my github link). You can see that I added additional constraints for all the bottom labels so that they add a Bottom Constraint to the ContentView (Just like you did with this.bornLabel). This had to be applied to all the labels on the bottom of the cell. This gives AutoLayout enough information to properly calculate the cell height.
Third, This almost works, but if you rotate to Landscape, you'll notice that the long name cells will be bigger and have extra padding. To fix this, I created another class called AutoLayoutLabel that inherits from UILabel. I overrode the Bounds property so that it changes the PreferredMaxLayoutWidth to the proper width when rotated to Landscape, and back to Portrait. You then will need to use AutoLayoutLabel instead of UILabel. You'll need this for all labels that need to wrap. I'm not sure how to set PreferredMaxLayoutWidth to auto in code, but this is how to do it programmatically (which also works for iOS 7).
public class AutoLayoutLabel : UILabel
{
public override CGRect Bounds
{
get
{
return base.Bounds;
}
set
{
base.Bounds = value;
if(this.Lines == 0 && Bounds.Size.Width != PreferredMaxLayoutWidth)
{
PreferredMaxLayoutWidth = Bounds.Size.Width;
SetNeedsUpdateConstraints();
}
}
}
}
Well, that should do it!
I now have a solution to this part of my issue. Prompted by #SharpMobileCode reference to PreferredMaxLayoutWidth I decided to give that another go. Rather that setting it to Automatic (which seems impossible in code) I am setting it Explicitly, once AutoLayout has done its thing. Like this
/// <summary>
/// Lays out subviews.
/// </summary>
public override void LayoutSubviews()
{
base.LayoutSubviews();
this.nameLabel.PreferredMaxLayoutWidth = this.nameLabel.Frame.Size.Width;
}
I am no longer seeing the Labels not wrap (hurrah!) however I am seeing an issue with what looks like cell reuse. Once I scroll all of the cell off the top of the screen I can scroll it back on and it has reverted to the same height as all the other cells. I can see the label is still wrapping but the cell height is wrong.
The standard table views in MvvmCross date back to iOS4 - while the new UITableViewAutomaticDimension sizing wasn't really added until much more recently (iOS8?)
Most real apps tend to use custom cells rather than the standard ones, but if you do want to use the standard ones, then I'd guess you could try adding some code to the setters in the cell which would trigger resize recalculations - e.g. to setters in https://github.com/MvvmCross/MvvmCross/blob/3.5/Cirrious/Cirrious.MvvmCross.Binding.Touch/Views/MvxStandardTableViewCell.cs#L73
I would guess that judiciously placed calls in there to request layout recalc would cause the parent cell and table to redraw.

Hide Controls At Design-Time [duplicate]

I need to handle multiple panels, containing variuous data masks. Each panel shall be visible using a TreeView control.
At this time, I handle the panels visibility manually, by making the selected one visible and bring it on top.
Actually this is not much confortable, especially in the UI designer, since when I add a brand new panel I have to resize every panel and then design it...
A good solution would be using a TabControl, and each panel is contained in a TabPage. But I cannot find any way to hide the TabControl buttons, since I already have a TreeView for selecting items.
Another solution would be an ipotethic "StackPanelControl", where the Panels are arranged using a stack, but I couldn't find it anywhere.
What's the best solution to handle this kind of UI?
You need a wee bit of Win32 API magic. The tab control sends the TCM_ADJUSTRECT message to allow the app to adjust the tab size. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form.
You'll get the tabs at design time so you can easily switch between pages. The tabs are hidden at runtime, use the SelectedIndex or SelectedTab property to switch between "views".
using System;
using System.Windows.Forms;
class StackPanel : TabControl {
protected override void WndProc(ref Message m) {
// Hide tabs by trapping the TCM_ADJUSTRECT message
if (m.Msg == 0x1328 && !DesignMode) m.Result = (IntPtr)1;
else base.WndProc(ref m);
}
}
A good solution would be using a TabControl, and each panel is contained in a TabPage.
But I cannot find any way to hide the TabControl buttons, since I already have a
TreeView for selecting items.
For the above,
You need to set the following properties of TabControl.
tabControl.Multiline = true;
tabControl.Appearance = TabAppearance.Buttons;
tabControl.ItemSize = new System.Drawing.Size(0, 1);
tabControl.SizeMode = TabSizeMode.Fixed;
tabControl.TabStop = false;

How to set background image for Dialog?

I am trying to do this:
public class DialogMenuHawaii extends Dialog {
Style s = UiFactory.getBaseStyle();
s.setBgTransparency(0);
s.setBgImage( <my image >);
this.setUnselectedStyle(s);
}
but it doesn't work.
First, I suggest you use a theme. We constantly change small implementation details e.g. customizations like the one you are doing will not be portable between LWUIT 1.4 and 1.5. There is no reason whatsoever not to use a theme for something like this.
If you are interested in the pain and suffering of manually coding view logic into your application you can use several methods such as getDialogComponent() to get the style from them and manipulate that. Dialog is a complex beast due to the fact that its really a form padded away from the edges.
Open your '.res' file in resource Editor and select your preferred theme,
Under 'Unselected' tab open the DialogContentPane style, if you don't have one create it look at the end of this answer on HOW TO DO IT?, and set the background image to the image you need to show as Dialog bg
Under 'Unselected' tab open the DialogBody style, if you don't have one create it look at the end of this answer on HOW TO DO IT?, and set the background transparency as '0' and also make sure the background image type is NONE
NOTE: The above code will reflect for all the Dialogs in your application. If you want a particular dialog with background image than derive new styles from these default styles, and follow the above steps to apply it to your DialogMenuHawaii or any runtime Dialogs.
HOW TO: I would recommend you to go through the Shai's blog posts LWUIT Resource Editor Tutorial Part 1 till part 10. To better understand the Resouce Editor its features and capabilities.
:
:
:
PS: Programmatic-ally i haven't been able to achieve it using TextArea which is the case for default Dialog's. If you replace the dialog body component with Label if works fine, the code sample is given below. I haven't delved much into why is it so ? maybe will do it in my free time. Hence i have proposed a working alternative solution which is scripted above using Resource Editor and below using the code
class MyDialog extends Dialog {
public void show() {
Container octnPane = this.getDialogComponent();
octnPane.getUnselectedStyle().setBgTransparency(0, false);
Container ctnPane = (Container)((BorderLayout)octnPane.getLayout()).getCenter();
ctnPane.getUnselectedStyle().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED, false);
ctnPane.getUnselectedStyle().setBgImage(myImage, false);
Label t = new Label("Dialog");
t.setUIID("DialogBody");
t.getUnselectedStyle().setBgTransparency(0, false);
ctnPane.addComponent(t);
super.show();
}
}
This is for Dialog background.
Dialog dialog = new Dialog();
dialog.getDialogStyle().setBgImage(Image.createImage("/image/image.png"));
If you want to set transparency of Dialog with image.
dialog.getStyle().setBgImage(Image.createImage("/image/image.png");

How do I make MFC checkbox read-only but keep text enabled?

It seems that disabling a checkbox through the Disabled property also grays out the caption. Does anyone know how to keep the caption enabled but disable input?
EDIT
Based on Paul's idea, I've done the following (now that I figured out that the static label and checkbox has a transparent property).
Added a couple checkboxes.
Set the checkbox captions to nothing.
Set checkbox transparent property to true.
Add a couple labels beside checkbox.
Change transparent property of labels to true.
Expand the checkboxes to encompass the label (so clicking on the label will trigger the check box to change).
But, this gives me very weird results. When I expand the checkbox over the label, it covers the label even though both are transparent. Again, I'm new to MFC (I'm a C# guy) so maybe I'm missing something.
Just override the onClick event and toggle the checkbox back to the way it was before.
void CMyDialog::OnBnClickedMyCheckBox()
{
m_myCheckBox.SetCheck(!m_myCheckBox.GetCheck());
}
Just make use of the Auto property, and leave it unchecked.
When clicking on it, it will not toggle any more, so basically it will be read-only, but still work fine as output.
Check Box Properties: Styles Auto Creates a check box that, when
selected, automatically toggles between checked and unchecked states.
You must set this property to True if you are using a group of check
boxes with Dialog Data Exchange.
Type: Bool, Default: True.
The quick and simple workaround is to not use the checkbox' text member (set it to ""), size down the checkbox to just the click-able square and simply place a label next to the checkbox.
To get a little fancier you could create a custom control that hosts a checkbox and a label which would enable reuse. It wold also be easier way to make the custom checkbox behave as expected for the end user e.g. being able to set the checkbox to selected or unselected when the label gets clicked as well as the checkbox itself. (The simple solution would not automatically relate the label and the checkbox. You could code that within the form but that might get ugly fast if you tend to reuse the paradigm.)
You could also look around for a 3rd-party checkbox control (there are numerous MFC UI libraries out there) but that might be overkill.
See this pseudo-layout:
You have this: (lone check box control)
[x "checkbox text"]
Lay it out like this: (label control aligned right next to the checkbox)
[x][label: "label text"]
Handle the clicked event of the label with something like:
void OnLabelClick(...) {
if (checkBox.Enabled)
checkBox.Checked = !checkBox.Checked;
}
You could un-select the box in the on-click function unless another condition exists.
void SetCheckBoxReadOnly(CButton* i_checkBox, bool i_readOnly)
{
if (!i_checkBox)
{
return;
}
// Clear/set "Auto" property
if (i_readOnly)
{
i_checkBox->ModifyStyle(BS_AUTOCHECKBOX, BS_CHECKBOX);
}
else
{
i_checkBox->ModifyStyle(BS_CHECKBOX, BS_AUTOCHECKBOX);
}
// Set a grey background for check square - looks like disabled :)
i_checkBox->SetState(i_readOnly ? TRUE : FALSE);
}

Resources