对于用户界面,我正在编写一个uitable
. 用户在第一列中选择选项A、B 或 C,第二列中的子选项取决于第一列中选择的内容,A.1,A.2 或 A.3或B.1,B.2或 B.3或C相同
该表的代码可在附录 A中找到。
当用户首先定义主选项时,子选项会自动相应地减少为只有有效的选项。这是通过评估CellEditCallback
for column 1并重置ColumnFormat
for column 2来实现的。(附录BmodifySelection
中的功能)如果用户现在意识到他犯了一个错误并且需要再次编辑一个子选项,那么仍然根据之前编辑的设置主选项和有效选项不可用,除非他再次重新选择主选项。(请参见图片中的蓝色突出显示)。ColumnFormat
为了解决这个问题,我还实现了CellSelectionCallback
调用函数justifySelection
(在附录 B中),该函数通过选择进行检查,在第 1 列中选择了哪个选项以再次为第 2 列提供正确的子选项。但是当这个回调对选择做出反应时,我需要选择两次,一次触发CellSelectionCallback
,另一次实际得到我的选择。对于大桌子,这可能很烦人!
所以我的问题是:
有没有办法阻止第 2 列中的弹出菜单弹出,直到它发现相应第 1 列的内容是什么,所以它立即提供有效的选择?
或者:
如何检测鼠标单击单元格并获取行和列索引?但是没有调用以下选择并弹出操作?
我已经在搜索所有可用的属性,但没有找到任何有用的东西。也许可以使用 做某事ButtonDownFcn
,但如何获取单元格索引?财产呢BusyAction
,如何用于我的目的?
有任何想法吗?
我很抱歉提前用这么多代码轰炸你,它已经是最小的例子,但完全可执行,所以你可以尝试一下。
附录 A/B
function fancyUitable
selector_1 = { 'A'; 'B' ; 'C' };
selector_2 = { 'first select first row!' };
h = figure('Position',[200 100 268 120],'numbertitle','off','MenuBar','none');
defaultData = repmat( {'select main option...', 'select suboption...'} ,5,1);
columnname = {'Option ',...
'Suboption '};
columnformat = { {selector_1{:}}, selector_2 };
columneditable = [true true];
t = uitable(h,'Units','normalized','Position',[0 0 1 1],...
'Data', defaultData,...
'ColumnName', columnname,...
'ColumnEditable', columneditable,...
'ColumnFormat', columnformat,...
'RowName',[],...
'CellEditCallback',@modifySelection,...
'CellSelectionCallback',@justifySelection);
set(h,'Tag','Config_figure')
set(t,'Tag','Config_table')
end
% **Appendix B**
% (part of the same function file)
function modifySelection(~,evt_edit)
if evt_edit.Indices(2) == 1
modifyPopup( evt_edit.Indices(1) );
end
end
function justifySelection(~,evt_select)
try %to surpress an unimportant error
if evt_select.Indices(2) == 2
modifyPopup( evt_select.Indices(1) );
end
end
end
最后是modifyPopup
重写的单个函数Columnformat
:
function modifyPopup( row )
id_group_1 = {'A.1';'A.2';'A.3'};
id_group_2 = {'B.1';'B.2';'B.3'};
id_group_3 = {'C.1';'C.2';'C.3'};
id_default = {'select main option first'};
myfigure = findobj('Tag','Config_figure');
config_data = get(findobj(myfigure,'Tag','Config_table'),'Data');
selector = config_data(row,1);
selector = selector{1};
config_format = get(findobj(myfigure,'Tag','Config_table'),'ColumnFormat');
switch selector
case 'A'
config_format{2} = id_group_1';
case 'B'
config_format{2} = id_group_2';
case 'C'
config_format{2} = id_group_3';
otherwise
config_format{2} = id_default;
end
set(findobj(myfigure,'Tag','Config_table'),'ColumnFormat',config_format)
end
赏金:为什么只是+50?- 我想这是不可能的,或者答案很简单,一旦一个人有了正确的初步想法。我不是在寻找使用 java 对象属性等的复杂解决方法。提前谢谢你!
我在此处包含评论中的讨论以保持概述:
如果您想尝试一下,可以复制代码并按照以下步骤重现不良行为:
- 在第一行中选择主要选项 A。
- 第一行中的子选项则包含选项 A.1、A.2 和 A.3。
- 选择第二行的主选项B,因此第二行的子选项的选择是B.1、B.2和B.3
- 但是现在您想(直接)更改第一行中的子选项;你会期望得到选项 A.1、A.2 和 A.3;但你没有。您将获得 B.1、B.2 和 B.3;- 因为您选择的最后一个主要选项是 B(尽管在不同的行中)。
看来,您应该查看相关选项,而不是寻找最后一个选项。因此,要么确保单击子选项进行“查找”以查看存在哪个主选项,
这正是我正在寻找的!但我怎么能这样做呢?如何检测点击,获取列&行索引,设置正确
ColumnFormat
,最后让单元格弹出。到目前为止,我看到的唯一可能性是CellSelectionCallback
,但它是在单元格已经弹出无效选项后执行的。我需要一种ClickedCallback
,就像有pushbuttons
或确保选择主选项仅设置该行的子选项。
这是不可能的,您不能根据需要为某行设置子选项 modify ColumnFormat
,这会影响整个表而不仅仅是一行。