[英]C# WPF Bindings not updating until MouseOut
我有一個帶有可單擊標簽(草和單位)的木板,當我單擊草標簽時,應將單位標簽移到草的x和y位置。 它有效,但是有點不對。 當我單擊標簽時,什么都沒有發生,直到我將光標移出所單擊的標簽,然后執行所需的行為。
XAML
<local:Grass Grid.Row="9" Grid.Column="16" />
<local:Unit Grid.Row="{Binding Path=xPos, UpdateSourceTrigger=PropertyChanged}" Grid.Column="{Binding Path=yPos, UpdateSourceTrigger=PropertyChanged}" >
<local:Unit.Background>
<ImageBrush ImageSource="Images/tjej.png"/>
</local:Unit.Background>
</local:Unit>
ObjectInspector
public class ObjectInspector : INotifyPropertyChanged
{
private int _xPos = 1, _yPos = 2;
public int xPos
{
get { return _xPos; }
set
{
_xPos = value;
NotifyPropertyChanged("xPos");
}
}
public int yPos
{
get { return _yPos; }
set {
_yPos = value;
NotifyPropertyChanged("yPos");
}
}
private string _type = "none";
public string type
{
get { return _type; }
set {
_type = value;
NotifyPropertyChanged("type");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
System.Diagnostics.Debug.WriteLine("property changed");
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
草
public class Grass : Button
{
protected override void OnClick()
{
base.OnClick();
int x = (int)this.GetValue(Grid.RowProperty);
int y = (int)this.GetValue(Grid.ColumnProperty);
string type = this.GetType().Name;
MainWindow.objectInspector.xPos = x;
MainWindow.objectInspector.yPos = y;
MainWindow.objectInspector.type = type;
}
}
主窗口
public partial class MainWindow : Window
{
public static ObjectInspector objectInspector= new ObjectInspector();
public MainWindow()
{
InitializeComponent();
this.DataContext = objectInspector;
}
}
有任何想法嗎?
編輯添加的MainWindow和Grass
編輯
嘗試注冊到公共事件處理程序, Click
按鈕:
<local:Grass Grid.Row="9" Grid.Column="16" Click="ClickEventHandler" />
...
在事件處理程序方法中,從發件人處獲取grass元素。
無論如何,我認為使用MVVM模式是更好的方法。 您可以設置GrassViewModel
和UnitViewModel
。 然后為每個創建一個DataTemplate
。 例如:
<DataTemplate DataType="{x:Type ViewModel:UnitViewModel}">
...Visual Elements Here...
</DataTemplate>
用於顯示網格中的元素的,您可以將ListBox
與Grid
as Items面板一起使用,如下所示:
<ListBox ItemsSource={Binding AllItemsCollection}>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
...rows and columns definitions here...
</Grid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<!--HERE THE ITEMS STYLE, HERE YOU SET THE COLUMN, ROW BINDINGS-->
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Grid.Row" Value="{Binding yPos}"/>
<Setter Property="Grid.Column" Value="{Binding xPos}"/>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
然后,您只需要在視圖模型中使用所需的所有元素創建AllItemsCollection
。 您可以使用行為來處理click事件,或為草創建UserControl(並在內部控制click事件):
<DataTemplate DataType="{x:Type ViewModel:UnitViewModel}">
<GrassUserControl ...Inside the grass user control you can handler the click event.../>
</DataTemplate>
希望可以幫助...
如果您使用以下MVVM,則可以按如下所示將屬性附加到標簽。 您可以將此行為附加到任何從UIElement派生的控件
為MouseClick創建一個附加屬性
public class MouseClick
{
public static readonly DependencyProperty MouseLeftClickProperty =
DependencyProperty.RegisterAttached("MouseLeftClick", typeof(ICommand), typeof(MouseClick),
new FrameworkPropertyMetadata(CallBack));
public static void SetMouseLeftClick(DependencyObject sender, ICommand value)
{
sender.SetValue(MouseLeftClickProperty, value);
}
public static ICommand GetMouseLeftClick(DependencyObject sender)
{
return sender.GetValue(MouseLeftClickProperty) as ICommand;
}
public static readonly DependencyProperty MouseEventParameterProperty =
DependencyProperty.RegisterAttached(
"MouseEventParameter",
typeof(object),
typeof(MouseClick),
new FrameworkPropertyMetadata((object)null, null));
public static object GetMouseEventParameter(DependencyObject d)
{
return d.GetValue(MouseEventParameterProperty);
}
public static void SetMouseEventParameter(DependencyObject d, object value)
{
d.SetValue(MouseEventParameterProperty, value);
}
private static void CallBack(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (sender != null)
{
UIElement element = sender as UIElement;
if (element != null)
{
if (e.OldValue != null)
{
element.RemoveHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(Handler));
}
if (e.NewValue != null)
{
element.AddHandler(UIElement.MouseDownEvent, new MouseButtonEventHandler(Handler), true);
}
}
}
}
private static void Handler(object sender, EventArgs e)
{
UIElement element = sender as UIElement;
if (sender != null)
{
ICommand cmd = element.GetValue(MouseLeftClickProperty) as ICommand;
if (cmd != null)
{
RoutedCommand routedCmd =cmd as RoutedCommand;
object paramenter = element.GetValue(MouseEventParameterProperty);
if (paramenter == null)
{
paramenter = element;
}
if (routedCmd != null)
{
if (routedCmd.CanExecute(paramenter, element))
{
routedCmd.Execute(paramenter, element);
}
}
else
{
if (cmd.CanExecute(paramenter))
{
cmd.Execute(paramenter);
}
}
}
}
}
}
在您的Xaml中,如下附加viewModel的命令
<Label Height="30" Width="200" Margin="10" Content="Click" local:MouseClick.MouseLeftClick="{Binding Click}" />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.