Здравствуйте, vpk, Вы писали:
vpk>Но хотелось бы, чтобы при клике по чекбоксу, он менял состояние, а не открывался комбобокс. vpk>Можно ли так сделать?
Либо полностью переписав ControlTemplate ComboBox'а, либо извратиться и поменять нечто в уже созданном контроле. Дело в том, что часть слева перекрывает прозрачный ToggleButton (можешь глянуть утилиткой Snoop), который не дает клику мышки проникнуть под него. Отнять у него этот перехват невозможно. Поэтому единственный вариант — сократить его ширину, чтобы он не перекрывал наш контрол (см. код ниже). Недостаток в том, что Popup не выскакивает при клике на строчку текста, но это тоже решается. Чтобы в code-behind не было мусора, весь код можно инкапсулировать в attached-property.
void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
var comboBox = (ComboBox)sender;
ModifyComboBoxTemplate(comboBox);
}
void ModifyComboBoxTemplate(ComboBox comboBox)
{
var popup = (Popup)comboBox.Template.FindName("PART_Popup", comboBox);
var root = GetRoot<ComboBox>(popup);
var toggleButton = SearchDownFirstChild<ToggleButton>(root);
toggleButton.SetValue(Grid.ColumnSpanProperty, 1);
toggleButton.SetValue(Grid.ColumnProperty, 2);
}
DependencyObject GetRoot<T>(DependencyObject child) where T : DependencyObject
{
var parent = child;
do
{
parent = VisualTreeHelper.GetParent(parent);
}
while (parent != null && !(parent is T));
return parent;
}
T SearchDownFirstChild<T>(DependencyObject parent) where T : DependencyObject
{
var childrentCount = VisualTreeHelper.GetChildrenCount(parent);
for (int childIndex = 0; childIndex < childrentCount; childIndex++)
{
var child = VisualTreeHelper.GetChild(parent, childIndex);
if (child is T)
{
return (T)child;
}
else
{
child = SearchDownFirstChild<T>(child);
if (child != null)
{
return (T)child;
}
}
}
return null;
}
Здравствуйте, Fortnum, Вы писали:
F>Либо полностью переписав ControlTemplate ComboBox'а, либо извратиться и поменять нечто в уже созданном контроле. Дело в том, что часть слева перекрывает прозрачный ToggleButton (можешь глянуть утилиткой Snoop), который не дает клику мышки проникнуть под него. Отнять у него этот перехват невозможно. Поэтому единственный вариант — сократить его ширину, чтобы он не перекрывал наш контрол (см. код ниже). Недостаток в том, что Popup не выскакивает при клике на строчку текста, но это тоже решается. Чтобы в code-behind не было мусора, весь код можно инкапсулировать в attached-property.
Такое решение не совместимо с Aero
Во-первых combobox меняет внешний вид, но это еще можно пережить, а во-вторых клики на чекбоксе все равно не работают.
Здравствуйте, vpk, Вы писали:
vpk>Такое решение не совместимо с Aero vpk>Во-первых combobox меняет внешний вид, но это еще можно пережить, а во-вторых клики на чекбоксе все равно не работают.
Просто посмотри Snoop'ом, что надо поправить в Aero. Способ работы со сгенеренным по шаблону контролом — тот же. Там из-за эффектов и внешнего вида, наверняка, абсолютно иной ControlTemplate, чем в Luna. Я для себя решил полностью переписать ControlTemplate, когда мне это понадобилось. Правда лишился темизации и нескольких стандартных эффектов комбобокса (типа тени, я ее убрал для простоты), но все фунциклионировало. Отполировать можно и потом, хотя это смотря какая задача перед тобой стоит. Еще говорят, что Blend позволяет как-то легко эти шаблоны править, я не пробовал. Но суть та же.
Здравствуйте, Fortnum, Вы писали:
F>Здравствуйте, vpk, Вы писали:
F>Просто посмотри Snoop'ом, что надо поправить в Aero. Способ работы со сгенеренным по шаблону контролом — тот же. Там из-за эффектов и внешнего вида, наверняка, абсолютно иной ControlTemplate, чем в Luna. Я для себя решил полностью переписать ControlTemplate, когда мне это понадобилось. Правда лишился темизации и нескольких стандартных эффектов комбобокса (типа тени, я ее убрал для простоты), но все фунциклионировало. Отполировать можно и потом, хотя это смотря какая задача перед тобой стоит. Еще говорят, что Blend позволяет как-то легко эти шаблоны править, я не пробовал. Но суть та же.
Основываясь на твоем методе и посмотрев внимательно в бленде на шаблон, нашел решение:
void ModifyComboBoxTemplate(ComboBox comboBox)
{
var content = SearchDownFirstChild<ContentPresenter>(comboBox);
content.SetValue(UIElement.IsHitTestVisibleProperty, true); //Именно тут проблема
}
Еще немного нужно подправить ItemTemplate, чтобы при клике по тексту открывался комбик.
Здравствуйте, vpk, Вы писали:
vpk>Правда работает только в Aero
Я говорил, что это изврат Но можно использовать VisualStyleInformation, чтобы определиться, что за начинка была сгенерирована, и применять соответствующий метод.
Здравствуйте, vpk, Вы писали:
vpk>Хочу сделать комбик с галочками в елементах. vpk>Но хотелось бы, чтобы при клике по чекбоксу, он менял состояние, а не открывался комбобокс. vpk>Можно ли так сделать?
Сделать-то можно, но вот пользователю такой контрол будет, скорее всего, не удобен. Используйте или раскрывающееся меню (ContextMenu, или какую-нибудь реализацию drop-down button), или список (ListBox) с галочками. Если места мало, то можно воспользоваться Expander-ом, которому в заголовок помещать полезную информацию — будет как раз имитация подобного комбика.
vpk>Такое решение не совместимо с Aero
чтобы все работало, надо унаследоваться от ComboBox'а, поместить этот контрол в отдельную сборку, положить туда темплейты для всех системных тем (в папке themes должны присутствовать ResourceDictionary для каждой темы с правильными названиями типа Luna.NormalColor.xaml и т.д.) и добавить к сборке атрибут [assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly, ResourceDictionaryLocation.SourceAssembly)]. Тогда системные темы будут подхватываться на лету.
Не пробовала ни разу, было бы интересно проверить, можно ли обойтись без наследования и переобъявить системные стили для стандартного ComboBox'а.
Здравствуйте, notacat, Вы писали:
vpk>>Такое решение не совместимо с Aero N>чтобы все работало, надо унаследоваться от ComboBox'а, поместить этот контрол в отдельную сборку, положить туда темплейты для всех системных тем (в папке themes должны присутствовать ResourceDictionary для каждой темы с правильными названиями типа Luna.NormalColor.xaml и т.д.) и добавить к сборке атрибут [assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly, ResourceDictionaryLocation.SourceAssembly)]. Тогда системные темы будут подхватываться на лету. N>Не пробовала ни разу, было бы интересно проверить, можно ли обойтись без наследования и переобъявить системные стили для стандартного ComboBox'а.
Поместить это в ресурсы Application.Resorces и все комбобоксы подхватят этот стиль в дополнение к стандартному из текущей темы.
Здравствуйте, Vladek, Вы писали:
N>>Не пробовала ни разу, было бы интересно проверить, можно ли обойтись без наследования и переобъявить системные стили для стандартного ComboBox'а. V>Поместить это в ресурсы Application.Resorces и все комбобоксы подхватят этот стиль в дополнение к стандартному из текущей темы.
Это лишь бантики к горькой пилюле переписывания всего ControlTemplate'а ComboBox'а целиком
это для текущей системной темы будет работать. Т.е. если вы написали стиль под Aero, а кто-то вашу программу запустил под Classic темой — в UI получится ерунда. Именно что надо делать стили для всех тем разные