C# 在MVVM中更改CaretIndex时,没有通知我
我知道CaretIndex不是依赖项属性 所以我登记如下:C# 在MVVM中更改CaretIndex时,没有通知我,c#,wpf,silverlight,xaml,C#,Wpf,Silverlight,Xaml,我知道CaretIndex不是依赖项属性 所以我登记如下: public class TextBoxHelper : TextBox { public static readonly DependencyProperty CaretIndexProperty = DependencyProperty.Register (
public class TextBoxHelper : TextBox
{
public static readonly DependencyProperty CaretIndexProperty
= DependencyProperty.Register
(
"CaretIndex",
typeof(int),
typeof(TextBoxHelper),
new FrameworkPropertyMetadata
(
0,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
CaretIndexChanged
)
);
public static int GetCaretIndex(DependencyObject obj)
{
return (int)obj.GetValue(CaretIndexProperty);
}
public static void SetCaretIndex(DependencyObject obj, int value)
{
obj.SetValue(CaretIndexProperty, value);
}
//public new int CaretIndex
//{
// get { return (int)GetValue(CaretIndexProperty); }
// set { SetValue(CaretIndexProperty, value); }
//}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
CaretIndex = base.CaretIndex;
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
CaretIndex = base.CaretIndex;
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
CaretIndex = base.CaretIndex;
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
CaretIndex = base.CaretIndex;
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
CaretIndex = base.CaretIndex;
}
private static void CaretIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (obj is TextBox)
{
((TextBox)obj).CaretIndex = (int)e.NewValue;
}
}
}
<ComboBox x:Name="cbUnder" ItemsSource="{Binding GroupsAndCorrespondingEffects}"
IsEditable="True" SelectedItem="{Binding SelectedGroup, Mode=TwoWay}"
Text="{Binding InputValue, UpdateSourceTrigger=PropertyChanged}" TextSearch.TextPath="GroupName"
Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="3"
vm:TextBoxHelper.CaretIndex="{Binding CaretIndex, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.Resources>
<DataTemplate DataType="{x:Type vm:GroupAndCorrespondingEffect}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding GroupName}" Width="250">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsHighlighted}" Value="True">
<Setter Property="Foreground" Value="Blue" />
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Text="{Binding CorrespondingEffect}" />
</StackPanel>
</DataTemplate>
</ComboBox.Resources>
</ComboBox>
private int _caretIndex;
public int CaretIndex
{
get { return _caretIndex; }
set
{
_caretIndex = value;
OnPropertyChanged("CaretIndex");
if (InputValue != null && CaretIndex >= 0)
{
SelectionStart = CaretIndex;
Debug.WriteLine(string.Format("Selection Start : {0}", SelectionStart));
SelectionLength = InputValue.Length - CaretIndex;
Debug.WriteLine(string.Format("Selection Length : {0}", SelectionLength));
}
for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
{
string WordToSearch = InputValue;
if (_caretIndex != 0 && _caretIndex > 0)
{
WordToSearch = InputValue.Substring(0, _caretIndex);
}
if (WordToSearch != null)
{
GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
}
}
}
}
private string _inputValue;
public string InputValue
{
get { return _inputValue; }
set
{
_inputValue = value;
OnPropertyChanged("GroupsAndCorrespondingEffects");
if (InputValue != null && CaretIndex >= 0)
{
SelectionStart = CaretIndex;
Debug.WriteLine(string.Format("Selection Start : {0}", SelectionStart));
SelectionLength = InputValue.Length - CaretIndex;
Debug.WriteLine(string.Format("Selection Length : {0}", SelectionLength));
}
for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
{
string WordToSearch = _inputValue;
if (_caretIndex != 0 && _caretIndex > 0 && _caretIndex < _inputValue.Length)
{
WordToSearch = _inputValue.Substring(0, _caretIndex);
}
GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
}
}
}
然后,我在ViewModel中创建了一个名为CaretIndex的属性。它实现INotifyPropertyChanged接口
private int _caretIndex;
public int CaretIndex
{
get { return _caretIndex; }
set
{
_caretIndex = value;
OnPropertyChanged("CaretIndex");
}
}
然后,我在组合框中创建了绑定,如下所示:
public class TextBoxHelper : TextBox
{
public static readonly DependencyProperty CaretIndexProperty
= DependencyProperty.Register
(
"CaretIndex",
typeof(int),
typeof(TextBoxHelper),
new FrameworkPropertyMetadata
(
0,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
CaretIndexChanged
)
);
public static int GetCaretIndex(DependencyObject obj)
{
return (int)obj.GetValue(CaretIndexProperty);
}
public static void SetCaretIndex(DependencyObject obj, int value)
{
obj.SetValue(CaretIndexProperty, value);
}
//public new int CaretIndex
//{
// get { return (int)GetValue(CaretIndexProperty); }
// set { SetValue(CaretIndexProperty, value); }
//}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
CaretIndex = base.CaretIndex;
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
CaretIndex = base.CaretIndex;
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
CaretIndex = base.CaretIndex;
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
CaretIndex = base.CaretIndex;
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
CaretIndex = base.CaretIndex;
}
private static void CaretIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (obj is TextBox)
{
((TextBox)obj).CaretIndex = (int)e.NewValue;
}
}
}
<ComboBox x:Name="cbUnder" ItemsSource="{Binding GroupsAndCorrespondingEffects}"
IsEditable="True" SelectedItem="{Binding SelectedGroup, Mode=TwoWay}"
Text="{Binding InputValue, UpdateSourceTrigger=PropertyChanged}" TextSearch.TextPath="GroupName"
Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="3"
vm:TextBoxHelper.CaretIndex="{Binding CaretIndex, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.Resources>
<DataTemplate DataType="{x:Type vm:GroupAndCorrespondingEffect}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding GroupName}" Width="250">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsHighlighted}" Value="True">
<Setter Property="Foreground" Value="Blue" />
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Text="{Binding CorrespondingEffect}" />
</StackPanel>
</DataTemplate>
</ComboBox.Resources>
</ComboBox>
private int _caretIndex;
public int CaretIndex
{
get { return _caretIndex; }
set
{
_caretIndex = value;
OnPropertyChanged("CaretIndex");
if (InputValue != null && CaretIndex >= 0)
{
SelectionStart = CaretIndex;
Debug.WriteLine(string.Format("Selection Start : {0}", SelectionStart));
SelectionLength = InputValue.Length - CaretIndex;
Debug.WriteLine(string.Format("Selection Length : {0}", SelectionLength));
}
for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
{
string WordToSearch = InputValue;
if (_caretIndex != 0 && _caretIndex > 0)
{
WordToSearch = InputValue.Substring(0, _caretIndex);
}
if (WordToSearch != null)
{
GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
}
}
}
}
private string _inputValue;
public string InputValue
{
get { return _inputValue; }
set
{
_inputValue = value;
OnPropertyChanged("GroupsAndCorrespondingEffects");
if (InputValue != null && CaretIndex >= 0)
{
SelectionStart = CaretIndex;
Debug.WriteLine(string.Format("Selection Start : {0}", SelectionStart));
SelectionLength = InputValue.Length - CaretIndex;
Debug.WriteLine(string.Format("Selection Length : {0}", SelectionLength));
}
for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
{
string WordToSearch = _inputValue;
if (_caretIndex != 0 && _caretIndex > 0 && _caretIndex < _inputValue.Length)
{
WordToSearch = _inputValue.Substring(0, _caretIndex);
}
GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
}
}
}
我试过上面的代码,但它告诉我输入字符串的格式不正确
因此,我将上述代码替换为:
<Style TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<TextBox x:Name="PART_EditableTextBox" vm:TextBoxHelper.CaretIndex="{Binding CaretIndex, UpdateSourceTrigger=PropertyChanged}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
更新4
我的ViewModel中还有一个属性InputValue
private string _inputValue;
public string InputValue
{
get { return _inputValue; }
set
{
_inputValue = value;
OnPropertyChanged("GroupsAndCorrespondingEffects");
for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
{
string WordToSearch = _inputValue;
if (_caretIndex != 0 || _caretIndex != null)
{
WordToSearch = _inputValue.Substring(0, _caretIndex);
}
GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
}
}
}
在ViewModel中调用属性的过程如下:
public class TextBoxHelper : TextBox
{
public static readonly DependencyProperty CaretIndexProperty
= DependencyProperty.Register
(
"CaretIndex",
typeof(int),
typeof(TextBoxHelper),
new FrameworkPropertyMetadata
(
0,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
CaretIndexChanged
)
);
public static int GetCaretIndex(DependencyObject obj)
{
return (int)obj.GetValue(CaretIndexProperty);
}
public static void SetCaretIndex(DependencyObject obj, int value)
{
obj.SetValue(CaretIndexProperty, value);
}
//public new int CaretIndex
//{
// get { return (int)GetValue(CaretIndexProperty); }
// set { SetValue(CaretIndexProperty, value); }
//}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
CaretIndex = base.CaretIndex;
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
CaretIndex = base.CaretIndex;
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
CaretIndex = base.CaretIndex;
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
CaretIndex = base.CaretIndex;
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
CaretIndex = base.CaretIndex;
}
private static void CaretIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (obj is TextBox)
{
((TextBox)obj).CaretIndex = (int)e.NewValue;
}
}
}
<ComboBox x:Name="cbUnder" ItemsSource="{Binding GroupsAndCorrespondingEffects}"
IsEditable="True" SelectedItem="{Binding SelectedGroup, Mode=TwoWay}"
Text="{Binding InputValue, UpdateSourceTrigger=PropertyChanged}" TextSearch.TextPath="GroupName"
Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="3"
vm:TextBoxHelper.CaretIndex="{Binding CaretIndex, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.Resources>
<DataTemplate DataType="{x:Type vm:GroupAndCorrespondingEffect}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding GroupName}" Width="250">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsHighlighted}" Value="True">
<Setter Property="Foreground" Value="Blue" />
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Text="{Binding CorrespondingEffect}" />
</StackPanel>
</DataTemplate>
</ComboBox.Resources>
</ComboBox>
private int _caretIndex;
public int CaretIndex
{
get { return _caretIndex; }
set
{
_caretIndex = value;
OnPropertyChanged("CaretIndex");
if (InputValue != null && CaretIndex >= 0)
{
SelectionStart = CaretIndex;
Debug.WriteLine(string.Format("Selection Start : {0}", SelectionStart));
SelectionLength = InputValue.Length - CaretIndex;
Debug.WriteLine(string.Format("Selection Length : {0}", SelectionLength));
}
for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
{
string WordToSearch = InputValue;
if (_caretIndex != 0 && _caretIndex > 0)
{
WordToSearch = InputValue.Substring(0, _caretIndex);
}
if (WordToSearch != null)
{
GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
}
}
}
}
private string _inputValue;
public string InputValue
{
get { return _inputValue; }
set
{
_inputValue = value;
OnPropertyChanged("GroupsAndCorrespondingEffects");
if (InputValue != null && CaretIndex >= 0)
{
SelectionStart = CaretIndex;
Debug.WriteLine(string.Format("Selection Start : {0}", SelectionStart));
SelectionLength = InputValue.Length - CaretIndex;
Debug.WriteLine(string.Format("Selection Length : {0}", SelectionLength));
}
for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
{
string WordToSearch = _inputValue;
if (_caretIndex != 0 && _caretIndex > 0 && _caretIndex < _inputValue.Length)
{
WordToSearch = _inputValue.Substring(0, _caretIndex);
}
GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
}
}
}
现在,当我在组合框中键入第一个字符时:
CaretIndex = 0
CaretIndex = 0
InputValue = Text of combobox
CaretIndex = 1
CaretIndex = 1
CaretIndex = 1
InputValue = Text of combobox
CaretIndex = 2
CaretIndex = 2
InputValue = Text of combobox
CaretIndex = 3
在组合框中键入第二个字符时:
CaretIndex = 0
CaretIndex = 0
InputValue = Text of combobox
CaretIndex = 1
CaretIndex = 1
CaretIndex = 1
InputValue = Text of combobox
CaretIndex = 2
CaretIndex = 2
InputValue = Text of combobox
CaretIndex = 3
在组合框中键入第三个字符时:
CaretIndex = 0
CaretIndex = 0
InputValue = Text of combobox
CaretIndex = 1
CaretIndex = 1
CaretIndex = 1
InputValue = Text of combobox
CaretIndex = 2
CaretIndex = 2
InputValue = Text of combobox
CaretIndex = 3
等等
我在combobox中突出显示项目的逻辑基于CaretIndex中的更改。此逻辑写入InputValue
属性的set部分。但是由于上面提到的事实,在CaretIndex获取新值之前调用InputValue,我得到了不正确的突出显示
更新5-保留选择丢失
我在TextBoxHelper类中添加了SelectionStart和SelectionLength属性,因为它们不是依赖属性
代码如下:
public static readonly DependencyProperty BindableSelectionStartProperty
= DependencyProperty.RegisterAttached
(
"BindableSelectionStart",
typeof(int),
typeof(TextBoxHelper),
new PropertyMetadata
(
BindableSelectionStartChanged
)
);
public static readonly DependencyProperty BindableSelectionLengthProperty
= DependencyProperty.RegisterAttached
(
"BindableSelectionLength",
typeof(int),
typeof(TextBoxHelper),
new PropertyMetadata
(
BindableSelectionLengthChanged
)
);
public static int GetBindableSelectionStart(DependencyObject obj)
{
return (int)obj.GetValue(BindableSelectionStartProperty);
}
public static void SetBindableSelectionStart(DependencyObject obj, int value)
{
obj.SetValue(BindableSelectionStartProperty, value);
}
public int BindableSelectionStart
{
get
{
return (int)this.GetValue(BindableSelectionStartProperty);
}
set
{
this.SetValue(BindableSelectionStartProperty, value);
}
}
public static int GetBindableSelectionLength(DependencyObject obj)
{
return (int)obj.GetValue(BindableSelectionLengthProperty);
}
public static void SetBindableSelectionLength(DependencyObject obj, int value)
{
obj.SetValue(BindableSelectionLengthProperty, value);
}
public int BindableSelectionLength
{
get
{
return (int)this.GetValue(BindableSelectionLengthProperty);
}
set
{
this.SetValue(BindableSelectionLengthProperty, value);
}
}
private static void BindableSelectionStartChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBox)
{
((TextBox)d).SelectionStart = (int)e.NewValue;
}
}
private static void BindableSelectionLengthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBox)
{
((TextBox)d).SelectionLength = (int)e.NewValue;
}
}
protected override void OnSelectionChanged(RoutedEventArgs e)
{
base.OnSelectionChanged(e);
BindableSelectionStart = base.SelectionStart;
BindableSelectionLength = base.SelectionLength;
}
public sealed class TextBoxHelper: TextBox
{
public static readonly DependencyProperty MyCaretIndexProperty
= DependencyProperty.Register
(
"MyCaretIndex",
typeof(int),
typeof(TextBoxHelper),
new FrameworkPropertyMetadata
(
0,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
MyCaretIndexChanged
)
);
public static int GetMyCaretIndex(DependencyObject obj)
{
return (int)obj.GetValue(MyCaretIndexProperty);
}
public static void SetMyCaretIndex(DependencyObject obj, int value)
{
obj.SetValue(MyCaretIndexProperty, value);
}
public int MyCaretIndex
{
get { return (int)GetValue(MyCaretIndexProperty); }
set { SetValue(MyCaretIndexProperty, value); }
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
MyCaretIndex = base.CaretIndex;
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
MyCaretIndex = base.CaretIndex;
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
MyCaretIndex = base.CaretIndex;
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
MyCaretIndex = base.CaretIndex;
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
MyCaretIndex = base.CaretIndex;
}
private static void MyCaretIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (obj is TextBox)
{
((TextBox)obj).CaretIndex = (int)e.NewValue;
}
}
}
然后,我在ViewModel中创建了相应的属性
private int _selectionStart;
public int SelectionStart
{
get
{
return _selectionStart;
}
set
{
_selectionStart = value;
OnPropertyChanged("SelectionStart");
}
}
private int _selectionLength;
public int SelectionLength
{
get
{
return _selectionLength;
}
set
{
_selectionLength = value;
OnPropertyChanged("SelectionLength");
}
}
之后,我更改了ViewModel的CaretIndex
和InputValue
属性,如下所示:
public class TextBoxHelper : TextBox
{
public static readonly DependencyProperty CaretIndexProperty
= DependencyProperty.Register
(
"CaretIndex",
typeof(int),
typeof(TextBoxHelper),
new FrameworkPropertyMetadata
(
0,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
CaretIndexChanged
)
);
public static int GetCaretIndex(DependencyObject obj)
{
return (int)obj.GetValue(CaretIndexProperty);
}
public static void SetCaretIndex(DependencyObject obj, int value)
{
obj.SetValue(CaretIndexProperty, value);
}
//public new int CaretIndex
//{
// get { return (int)GetValue(CaretIndexProperty); }
// set { SetValue(CaretIndexProperty, value); }
//}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
CaretIndex = base.CaretIndex;
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
CaretIndex = base.CaretIndex;
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
CaretIndex = base.CaretIndex;
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
CaretIndex = base.CaretIndex;
}
protected override void OnMouseUp(MouseButtonEventArgs e)
{
base.OnMouseUp(e);
CaretIndex = base.CaretIndex;
}
private static void CaretIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (obj is TextBox)
{
((TextBox)obj).CaretIndex = (int)e.NewValue;
}
}
}
<ComboBox x:Name="cbUnder" ItemsSource="{Binding GroupsAndCorrespondingEffects}"
IsEditable="True" SelectedItem="{Binding SelectedGroup, Mode=TwoWay}"
Text="{Binding InputValue, UpdateSourceTrigger=PropertyChanged}" TextSearch.TextPath="GroupName"
Grid.Column="1" Grid.ColumnSpan="4" Grid.Row="3"
vm:TextBoxHelper.CaretIndex="{Binding CaretIndex, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.Resources>
<DataTemplate DataType="{x:Type vm:GroupAndCorrespondingEffect}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding GroupName}" Width="250">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsHighlighted}" Value="True">
<Setter Property="Foreground" Value="Blue" />
<Setter Property="FontWeight" Value="Bold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<TextBlock Text="{Binding CorrespondingEffect}" />
</StackPanel>
</DataTemplate>
</ComboBox.Resources>
</ComboBox>
private int _caretIndex;
public int CaretIndex
{
get { return _caretIndex; }
set
{
_caretIndex = value;
OnPropertyChanged("CaretIndex");
if (InputValue != null && CaretIndex >= 0)
{
SelectionStart = CaretIndex;
Debug.WriteLine(string.Format("Selection Start : {0}", SelectionStart));
SelectionLength = InputValue.Length - CaretIndex;
Debug.WriteLine(string.Format("Selection Length : {0}", SelectionLength));
}
for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
{
string WordToSearch = InputValue;
if (_caretIndex != 0 && _caretIndex > 0)
{
WordToSearch = InputValue.Substring(0, _caretIndex);
}
if (WordToSearch != null)
{
GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
}
}
}
}
private string _inputValue;
public string InputValue
{
get { return _inputValue; }
set
{
_inputValue = value;
OnPropertyChanged("GroupsAndCorrespondingEffects");
if (InputValue != null && CaretIndex >= 0)
{
SelectionStart = CaretIndex;
Debug.WriteLine(string.Format("Selection Start : {0}", SelectionStart));
SelectionLength = InputValue.Length - CaretIndex;
Debug.WriteLine(string.Format("Selection Length : {0}", SelectionLength));
}
for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
{
string WordToSearch = _inputValue;
if (_caretIndex != 0 && _caretIndex > 0 && _caretIndex < _inputValue.Length)
{
WordToSearch = _inputValue.Substring(0, _caretIndex);
}
GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
}
}
}
private int\u caretIndex;
公共int CaretIndex
{
获取{return\u caretIndex;}
设置
{
_caretIndex=值;
OnPropertyChanged(“CaretIndex”);
if(InputValue!=null&&CaretIndex>=0)
{
SelectionStart=CaretIndex;
Debug.WriteLine(string.Format(“选择开始:{0}”,选择开始));
SelectionLength=InputValue.Length-CaretIndex;
WriteLine(string.Format(“选择长度:{0}”,SelectionLength));
}
对于(int i=0;i0)
{
WordToSearch=InputValue.Substring(0,_caretIndex);
}
if(WordToSearch!=null)
{
GroupsAndCorrespondingEffects[i]。IsHighlighted=GroupsAndCorrespondingEffects[i]。GroupName.StartsWith(WordToSearch);
}
}
}
}
私有字符串_inputValue;
公共字符串输入值
{
获取{return}inputValue;}
设置
{
_输入值=值;
关于财产变更(“集团和相应影响”);
if(InputValue!=null&&CaretIndex>=0)
{
SelectionStart=CaretIndex;
Debug.WriteLine(string.Format(“选择开始:{0}”,选择开始));
SelectionLength=InputValue.Length-CaretIndex;
WriteLine(string.Format(“选择长度:{0}”,SelectionLength));
}
对于(int i=0;i0&&u caretIndex<\u inputValue.Length)
{
WordToSearch=\u inputValue.Substring(0,\u caretIndex);
}
GroupsAndCorrespondingEffects[i]。IsHighlighted=GroupsAndCorrespondingEffects[i]。GroupName.StartsWith(WordToSearch);
}
}
}
我在ResourceDictionary中做的最后一次更改如下:
<vm:TextBoxHelper x:Name="PART_EditableTextBox" MyCaretIndex="{Binding CaretIndex}"
BindableSelectionStart="{Binding SelectionStart}"
BindableSelectionLength="{Binding SelectionLength}"
...........
将问题与代码结合起来:
1) 通过在TextBoxHelper
中执行CaretIndex=base.CaretIndex
,您实际上是在设置相同的属性,该属性不会触发或更改任何内容
2) 您正在设置ComboBox
默认模板,但当IsEditable
为true时,您要设置的是ComboBox模板。否则,WPF会将您提供的模板作为默认模板,一旦您将IsEditable设置为true,WPF就会引入默认的可编辑模板,该模板使用TextBox,而不是用户TextBoxHelper
所以,这就是我所做的工作:
1) 已更新组合框样式,仅当IsEditable
为True
<Style TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}">
<Style.Triggers>
<Trigger Property="IsEditable" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<local:TextBoxHelper x:Name="PART_EditableTextBox" MyCaretIndex="{Binding CaretIndex}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
以及CaretIndex属性的my ViewModel代码供您参考:
public int CaretIndex
{
get { return _caretIndex; }
set
{
_caretIndex = value;
Trace.WriteLine(String.Format("Caret Index {0}", _caretIndex));
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("CaretIndex"));
}
}
查看代码:
<ComboBox ItemsSource="{Binding Items}" IsEditable="True" />
更新2
<TextBox x:Name="PART_EditableTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="vm:TextBoxHelper.CaretIndex" Value="{Binding CaretIndex, UpdateSourceTrigger=PropertyChanged}" />
.
.
.
修复所选文本丢失问题:
将TextBoxHelper
中的MyCaretIndexChanged方法更新为:
private static void MyCaretIndexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if (obj is TextBox && (int)e.OldValue != (int)e.NewValue)
{
var textBox = (TextBox) obj;
textBox.CaretIndex = (int)e.NewValue;
if (!string.IsNullOrEmpty(textBox.Text))
textBox.Select(textBox.CaretIndex, textBox.Text.Length - textBox.CaretIndex);
}
}
你有子类TextBox
来创建新的DP,但是combobox仍然在里面使用WPF TextBox。我现在可以做什么,让combobox使用我的子类?你必须覆盖combobox的模板
。你能给我一个链接到覆盖模板的任何教程/示例吗?如果可以,请发布我如何获得其他部分的内容组合框。我已将您更新的代码放入资源字典中。但是当CaretIndex发生变化时,我没有得到通知。我需要在组合框中引用资源字典吗?如果是,那么如何操作?您需要将resourcedictionary包含在您拥有组合框的usercontrol中。e、 g代码:
我没有使用UserControl。因此,我已经在App.xaml文件中添加了上述注释中的代码。但是当CaretIndex发生变化时,我没有得到通知。在您更新答案之前,我直接在Combobox.Resources部分中尝试了该代码,它给了我通知。可能有什么问题?我在app.xaml中尝试了更新的代码,结果很好。发布你的app.xaml。另外,当您在调试器下运行应用程序时,在输出窗口中是否看到任何绑定错误?