Я улучшил решение, которое использует регулярное выражение для Pinhassi, поэтому оно также правильно обрабатывает края. Прежде чем проверять правильность ввода, сначала окончательная строка построена, как описано в документах android.
public class DecimalDigitsInputFilter implements InputFilter {
private Pattern mPattern;
private static final Pattern mFormatPattern = Pattern.compile("\\d+\\.\\d+");
public DecimalDigitsInputFilter(int digitsBeforeDecimal, int digitsAfterDecimal) {
mPattern = Pattern.compile(
"^\\d{0," + digitsBeforeDecimal + "}([\\.,](\\d{0," + digitsAfterDecimal +
"})?)?$");
}
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest,
int dstart, int dend) {
String newString =
dest.toString().substring(0, dstart) + source.toString().substring(start, end)
+ dest.toString().substring(dend, dest.toString().length());
Matcher matcher = mPattern.matcher(newString);
if (!matcher.matches()) {
return "";
}
return null;
}
}
Использование:
editText.setFilters(new InputFilter[] {new DecimalDigitsInputFilter(5,2)});
Другой вариант - использовать привязку. Если у вас есть объект, с которым вы используете привязку для получения текста каждого TreeViewItem
(например), вы можете создать стиль, который также связывает свойство IsSelected
:
<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected"
Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.Resources>
</TreeView>
Это предполагает, что связанный объект имеет свойство IsSelected
типа bool
. Затем вы можете выбрать TreeViewItem
, установив для IsSelected
значение true
для соответствующего объекта.
Тот же подход можно использовать с IsExpanded
для управления раскрытием или сворачиванием TreeViewItem
.
TreeViewItem
(например), вы можете создать стиль, который также связывает свойство IsSelected
:
<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected"
Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.Resources>
</TreeView>
Это предполагает, что связанный объект имеет свойство IsSelected
типа bool
. Затем вы можете выбрать TreeViewItem
, установив для IsSelected
значение true
для соответствующего объекта.
Тот же подход можно использовать с IsExpanded
для управления раскрытием или сворачиванием TreeViewItem
.
TreeViewItem
(например), вы можете создать стиль, который также связывает свойство IsSelected
:
<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected"
Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.Resources>
</TreeView>
Это предполагает, что связанный объект имеет свойство IsSelected
типа bool
. Затем вы можете выбрать TreeViewItem
, установив для IsSelected
значение true
для соответствующего объекта.
Тот же подход можно использовать с IsExpanded
для управления раскрытием или сворачиванием TreeViewItem
.
<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected"
Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.Resources>
</TreeView>
Предполагается, что связанный объект имеет свойство IsSelected
типа bool
. Затем вы можете выбрать TreeViewItem
, установив для IsSelected
значение true
для соответствующего объекта.
Тот же подход можно использовать с IsExpanded
для управления раскрытием или сворачиванием TreeViewItem
.
<TreeView>
<TreeView.Resources>
<Style TargetType="TreeViewItem">
<Setter Property="IsSelected"
Value="{Binding Path=IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.Resources>
</TreeView>
Предполагается, что связанный объект имеет свойство IsSelected
типа bool
. Затем вы можете выбрать TreeViewItem
, установив для IsSelected
значение true
для соответствующего объекта.
Тот же подход можно использовать с IsExpanded
для управления раскрытием или сворачиванием TreeViewItem
.
Попробовав разные растворы, я пришел на на этот сайт. Чжоу Юн показывает, как программно расширить все узлы TreeView. В его методе есть две основные идеи:
Вот код, который я закончил с
public static void SelectItem(this ItemsControl parentContainer, List<object> path)
{
var head = path.First();
var tail = path.GetRange(1, path.Count - 1);
var itemContainer = parentContainer.ItemContainerGenerator.ContainerFromItem(head) as TreeViewItem;
if (itemContainer != null && itemContainer.Items.Count == 0)
{
itemContainer.IsSelected = true;
var selectMethod = typeof(TreeViewItem).GetMethod("Select", BindingFlags.NonPublic | BindingFlags.Instance);
selectMethod.Invoke(itemContainer, new object[] { true });
}
else if (itemContainer != null)
{
itemContainer.IsExpanded = true;
if (itemContainer.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
{
itemContainer.ItemContainerGenerator.StatusChanged += delegate
{
SelectItem(itemContainer, tail);
};
}
else
{
SelectItem(itemContainer, tail);
}
}
}
В моем случае (у меня была та же проблема), но было неуместно использовать привязку к свойству IsSelected объекта Data, а также я не мог легко получить путь к элементу дерева, поэтому следующий код отлично справился с задачей:
private void SelectTreeViewItem(object item)
{
try
{
var tvi = GetContainerFromItem(this.MainRegion, item);
tvi.Focus();
tvi.IsSelected = true;
var selectMethod =
typeof(TreeViewItem).GetMethod("Select",
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
selectMethod.Invoke(tvi, new object[] { true });
}
catch { }
}
private TreeViewItem GetContainerFromItem(ItemsControl parent, object item)
{
var found = parent.ItemContainerGenerator.ContainerFromItem(item);
if (found == null)
{
for (int i = 0; i < parent.Items.Count; i++)
{
var childContainer = parent.ItemContainerGenerator.ContainerFromIndex(i) as ItemsControl;
TreeViewItem childFound = null;
if (childContainer != null && childContainer.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
{
childContainer.ItemContainerGenerator.StatusChanged += (o, e) =>
{
childFound = GetContainerFromItem(childContainer, item);
};
}
else
{
childFound = GetContainerFromItem(childContainer, item);
}
if (childFound != null)
return childFound;
}
}
return found as TreeViewItem;
}
Да, метод ContainerFromItem ничего не возвращает, даже если вы вызываете его из прямого родительского TreeViewItem.
Возможно, вам придется немного изменить дизайн. Если вы создаете все как явный TreeViewItem, вы должны иметь возможность сохранить ссылку на него и установить для него IsSelected.