내 응용 프로그램에서 텍스트 상자의 모든 입력은 내가 직접 작성한 입력 상자에 의해 수행되어야합니다. 따라서 텍스트 상자를 클릭 할 때마다 입력 상자가 나타납니다. 다음과 같이 보입니다.
xaml의 텍스트 상자 :
<TextBox Text="{Binding Level}" Grid.Row="1" Grid.Column="2" Margin="2">
<TextBox.InputBindings>
<MouseBinding Command="{Binding EnterLevel}" MouseAction="LeftClick" />
</TextBox.InputBindings>
</TextBox>
VM의 명령 :
private void ExecuteEnterLevel()
{
var dialog = new BFH.InputBox.InputBox("Level", 1, 1, 4);
dialog.ShowDialog();
Level = Convert.ToInt16(dialog.Input);
}
따라서 입력 상자의 결과는 입력 상자의 텍스트가됩니다. 이것은 잘 작동합니다.
이제 내 질문은 : 모든 단일 텍스트 상자에 대한 이벤트를 코딩하지 않고도 해당 기능이 필요한 모든 텍스트 상자에 대해 그렇게 할 수 있습니까? 자동으로하는 "myTextbox"를 갖고 싶습니다.
지금까지 시도한 것 : 내 텍스트 상자 :
class MyTextbox : TextBox
{
public MyTextbox()
{
this.MouseDown += MyTextbox_MouseDown;
}
private void MyTextbox_MouseDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
TextBox tb = (TextBox)sender;
var dialog = new BFH.InputBox.InputBox("titel", "input");
dialog.ShowDialog();
tb.Text = dialog.Input;
}
}
그리고 xaml에서 :
<libraries:MyTextbox/>
그러나 MyTextbox_MouseDown
결코 실행되지 않습니다. MessageBox.Show("test")
결과없이 넣었습니다 . 내가 뭔가 잘못하고 있다고 생각합니다.
스타일에 InputBindings를 정의 할 수 없기 때문에 최소한 간단한 방식으로. AttachedProperties를 사용하여 문제를 해결할 것을 제안합니다.
연결된 속성에 대한 클래스를 정의하여 시작하겠습니다.
namespace CSharpWPF
{
class EventHelper
{
public static ICommand GetLeftClick(DependencyObject obj)
{
return (ICommand)obj.GetValue(LeftClickProperty);
}
public static void SetLeftClick(DependencyObject obj, ICommand value)
{
obj.SetValue(LeftClickProperty, value);
}
// Using a DependencyProperty as the backing store for LeftClick. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LeftClickProperty =
DependencyProperty.RegisterAttached("LeftClick", typeof(ICommand), typeof(EventHelper), new PropertyMetadata(null, OnLeftClickChanged));
private static void OnLeftClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement elem = d as FrameworkElement;
ICommand command = e.NewValue as ICommand;
if (command != null)
elem.InputBindings.Add(new MouseBinding(command, new MouseGesture(MouseAction.LeftClick)));
}
}
}
이것은 기본적으로 속성이 변경된 코드에서 마우스 바인딩의 번역입니다.
용법
<TextBox l:EventHelper.LeftClick="{Binding MyCommand}" />
모든 TextBox에 적용하려면 TextBox를 대상으로하는 일반 스타일로 동일하게 래핑합니다.
<Style TargetType="TextBox">
<Setter Property="l:EventHelper.LeftClick"
Value="{Binding MyCommand}" />
</Style>
l:
위에서 선언 한 클래스의 네임 스페이스를 참조합니다. xmlns:l="clr-namespace:CSharpWPF"
완전한 예
<StackPanel xmlns:l="clr-namespace:CSharpWPF">
<StackPanel.Resources>
<Style TargetType="TextBox">
<Setter Property="l:EventHelper.LeftClick"
Value="{Binding MyCommand}" />
</Style>
</StackPanel.Resources>
<TextBox />
<TextBox />
<TextBox />
<TextBox />
</StackPanel>
입력 상자 동작 연결
수업
class InputHelper
{
public static bool GetIsInputBoxEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(IsInputBoxEnabledProperty);
}
public static void SetIsInputBoxEnabled(DependencyObject obj, bool value)
{
obj.SetValue(IsInputBoxEnabledProperty, value);
}
// Using a DependencyProperty as the backing store for IsInputBoxEnabled. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsInputBoxEnabledProperty =
DependencyProperty.RegisterAttached("IsInputBoxEnabled", typeof(bool), typeof(InputHelper), new PropertyMetadata(false, OnIsInputBoxEnabled));
private static void OnIsInputBoxEnabled(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextBox tb = d as TextBox;
if ((bool)e.NewValue)
tb.PreviewMouseDown += elem_MouseDown;
else
tb.PreviewMouseDown -= elem_MouseDown;
}
static void elem_MouseDown(object sender, MouseButtonEventArgs e)
{
TextBox tb = sender as TextBox;
var dialog = new BFH.InputBox.InputBox(tb.GetValue(InputBoxTitleProperty), tb.GetValue(InputProperty));
dialog.ShowDialog();
tb.Text = dialog.Input;
}
public static string GetInputBoxTitle(DependencyObject obj)
{
return (string)obj.GetValue(InputBoxTitleProperty);
}
public static void SetInputBoxTitle(DependencyObject obj, string value)
{
obj.SetValue(InputBoxTitleProperty, value);
}
// Using a DependencyProperty as the backing store for InputBoxTitle. This enables animation, styling, binding, etc...
public static readonly DependencyProperty InputBoxTitleProperty =
DependencyProperty.RegisterAttached("InputBoxTitle", typeof(string), typeof(InputHelper), new PropertyMetadata(null));
public static string GetInput(DependencyObject obj)
{
return (string)obj.GetValue(InputProperty);
}
public static void SetInput(DependencyObject obj, string value)
{
obj.SetValue(InputProperty, value);
}
// Using a DependencyProperty as the backing store for Input. This enables animation, styling, binding, etc...
public static readonly DependencyProperty InputProperty =
DependencyProperty.RegisterAttached("Input", typeof(string), typeof(InputHelper), new PropertyMetadata(null));
}
용법
<TextBox l:InputHelper.IsInputBoxEnabled="true"
l:InputHelper.InputBoxTitle="Title"
l:InputHelper.Input="Input" />
또는 스타일을 통해
<Style TargetType="TextBox">
<Setter Property="l:InputHelper.IsInputBoxEnabled"
Value="true" />
<Setter Property="l:InputHelper.Title"
Value="true" />
<Setter Property="l:InputHelper.Input"
Value="Input" />
</Style>
연결된 속성을 사용하면이 동작을 기존 클래스에서 상속하는 대신 기존 클래스에 연결할 수 있습니다.
텍스트 상자 클래스를 상속하는 경우 동일한 속성에 두 개의 속성을 추가 할 수 있습니다.
예 :
class MyTextbox : TextBox
{
public MyTextbox()
{
this.PreviewMouseDown += MyTextbox_MouseDown;
}
private void MyTextbox_MouseDown(object sender, MouseButtonEventArgs mouseButtonEventArgs)
{
TextBox tb = (TextBox)sender;
var dialog = new BFH.InputBox.InputBox(InputBoxTitle, Input);
dialog.ShowDialog();
tb.Text = dialog.Input;
}
public string InputBoxTitle { get; set; }
public string Input { get; set; }
}
용법
<libraries:MyTextbox InputBoxTitle="Title"
Input="Input" />
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다