C# 如何创建全局按钮并根据WPF/C中的当前可见视图动态附加不同的处理程序?
我有一个WPF项目,有许多视图,每个视图有8个页脚按钮。页脚按钮触发属于视图的方法 我希望全局定义页脚按钮一次,并根据当前视图附加不同的单击侦听器 下面是一个更清楚的例子: 页脚按钮在(父)主窗口中创建。如果我导航到View1,第一个按钮将显示标签“Say Hello”,如果单击,它将显示消息“Hello”。如果我导航到View2,第一个按钮将显示标签“说再见”,如果单击,它将显示消息“再见” 我该怎么做?什么是好方法C# 如何创建全局按钮并根据WPF/C中的当前可见视图动态附加不同的处理程序?,c#,wpf,xaml,C#,Wpf,Xaml,我有一个WPF项目,有许多视图,每个视图有8个页脚按钮。页脚按钮触发属于视图的方法 我希望全局定义页脚按钮一次,并根据当前视图附加不同的单击侦听器 下面是一个更清楚的例子: 页脚按钮在(父)主窗口中创建。如果我导航到View1,第一个按钮将显示标签“Say Hello”,如果单击,它将显示消息“Hello”。如果我导航到View2,第一个按钮将显示标签“说再见”,如果单击,它将显示消息“再见” 我该怎么做?什么是好方法 提前谢谢你 此示例使用界面和带有按钮的用户控件(此处仅3个)。 Wind
提前谢谢你 此示例使用界面和带有按钮的用户控件(此处仅3个)。 Window1和Window2正在实现该接口。DataContext绑定到用户控件ButtonData属性 每个按钮在标记属性中都有一个索引。按钮单击事件处理程序对于所有按钮都是通用的,但是您可以为每个按钮定义一个事件处理程序 不要忘记并更改xaml中的名称空间 接口IViewButtons.cs
public interface IViewButtons
{
List<string> ButtonNames { get; set; }
void Button_Click(object sender, RoutedEventArgs e);
}
MainWindow.xaml
<Window x:Class="WpfApp11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp11"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel Orientation="Horizontal">
<Button x:Name="BtnView1" Content="View 1" Click="BtnView1_Click" VerticalAlignment="Top" Margin="5"/>
<Button x:Name="BtnView2" Content="View 2" Click="BtnView2_Click" VerticalAlignment="Top" Margin="5"/>
</StackPanel>
</Grid>
</Window>
<Window x:Class="WpfApp11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp11"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button x:Name="BtnView1" Content="View 1" Click="BtnView1_Click" VerticalAlignment="Top" Margin="5"/>
<Button x:Name="BtnView2" Content="View 2" Click="BtnView2_Click" VerticalAlignment="Top" Margin="5"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button Content="{Binding ButtonNames[0]}" Tag="0" Click="YourButtons_Click" Margin="5"/>
<Button Content="{Binding ButtonNames[1]}" Tag="1" Click="YourButtons_Click" Margin="5"/>
<Button Content="{Binding ButtonNames[2]}" Tag="2" Click="YourButtons_Click" Margin="5"/>
</StackPanel>
</Grid>
</Window>
Window1.xaml
<Window x:Class="WpfApp11.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp11"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<local:YourButtons Grid.Row="1" ButtonData="{Binding}"/>
</Grid>
</Window>
Window1.xaml.cs
public partial class Window1 : Window, IViewButtons
{
public Window1()
{
DataContext = this;
InitializeComponent();
}
void IViewButtons.Button_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
if (int.Parse(btn.Tag.ToString()) == 0)
MessageBox.Show("Hello");
else
MessageBox.Show("Btn " + btn.Tag + " pressed");
}
public List<string> ButtonNames { get; set; } = new List<string>()
{
"Say Hello",
"Btn 2",
"Btn 3"
};
}
公共部分类窗口1:窗口,IViewButtons
{
公共窗口1()
{
DataContext=this;
初始化组件();
}
无效IViewButtons.按钮单击(对象发送器,路由EventTargets e)
{
按钮btn=(按钮)发送器;
if(int.Parse(btn.Tag.ToString())==0)
MessageBox.Show(“你好”);
其他的
MessageBox.Show(“Btn”+Btn.Tag+“按下”);
}
公共列表按钮名称{get;set;}=new List()
{
“打招呼”,
“Btn 2”,
“Btn 3”
};
}
Window2.xaml
<Window x:Class="WpfApp11.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp11"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<local:YourButtons Grid.Row="1" ButtonData="{Binding}"/>
</Grid>
</Window>
Window2.xaml.cs
public partial class Window2 : Window, IViewButtons
{
public Window2()
{
DataContext = this;
InitializeComponent();
}
void IViewButtons.Button_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)sender;
if (int.Parse(btn.Tag.ToString()) == 0)
MessageBox.Show("Goodbye");
else
MessageBox.Show("Btn " + btn.Tag + " pressed");
}
public List<string> ButtonNames { get; set; } = new List<string>()
{
"Say Goodbye",
"Btn 2",
"Btn 3"
};
}
公共部分类窗口2:窗口,IViewButtons
{
公共窗口2()
{
DataContext=this;
初始化组件();
}
无效IViewButtons.按钮单击(对象发送器,路由EventTargets e)
{
按钮btn=(按钮)发送器;
if(int.Parse(btn.Tag.ToString())==0)
MessageBox.Show(“再见”);
其他的
MessageBox.Show(“Btn”+Btn.Tag+“按下”);
}
公共列表按钮名称{get;set;}=new List()
{
“说再见”,
“Btn 2”,
“Btn 3”
};
}
编辑:
第2版:
我没注意到你想要主窗口的按钮。因此,此版本在主Windows XAML中有按钮(无需用户控制)。使用相同的接口。Window1和Window2没有XAML,但后面的代码相同
如果用户打开多个窗口,则必须进行处理
MainWindow.xaml
<Window x:Class="WpfApp11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp11"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel Orientation="Horizontal">
<Button x:Name="BtnView1" Content="View 1" Click="BtnView1_Click" VerticalAlignment="Top" Margin="5"/>
<Button x:Name="BtnView2" Content="View 2" Click="BtnView2_Click" VerticalAlignment="Top" Margin="5"/>
</StackPanel>
</Grid>
</Window>
<Window x:Class="WpfApp11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp11"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button x:Name="BtnView1" Content="View 1" Click="BtnView1_Click" VerticalAlignment="Top" Margin="5"/>
<Button x:Name="BtnView2" Content="View 2" Click="BtnView2_Click" VerticalAlignment="Top" Margin="5"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button Content="{Binding ButtonNames[0]}" Tag="0" Click="YourButtons_Click" Margin="5"/>
<Button Content="{Binding ButtonNames[1]}" Tag="1" Click="YourButtons_Click" Margin="5"/>
<Button Content="{Binding ButtonNames[2]}" Tag="2" Click="YourButtons_Click" Margin="5"/>
</StackPanel>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void BtnView1_Click(object sender, RoutedEventArgs e)
{
Window1 window1 = new Window1();
window1.Show();
}
private void BtnView2_Click(object sender, RoutedEventArgs e)
{
Window2 window2 = new Window2();
window2.Show();
}
}
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public MainWindow()
{
DataContext = this;
InitializeComponent();
}
//Bound to the buttons content
public List<string> ButtonNames
{
get { return _buttonNames; }
set
{
_buttonNames = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ButtonNames)));
}
}
private List<string> _buttonNames;
//Contains the current Window, used for accessing the windows implementation of IViewButtons
IViewButtons currentWindow;
private void BtnView1_Click(object sender, RoutedEventArgs e)
{
Window1 window1 = new Window1();
currentWindow = window1;
ButtonNames = currentWindow.ButtonNames;
window1.Show();
}
private void BtnView2_Click(object sender, RoutedEventArgs e)
{
Window2 window2 = new Window2();
currentWindow = window2;
ButtonNames = currentWindow.ButtonNames;
window2.Show();
}
private void YourButtons_Click(object sender, RoutedEventArgs e)
{
//Forwarding the event to the windows event handler
currentWindow.Button_Click(sender, e);
}
}
public分部类主窗口:窗口,INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
公共主窗口()
{
DataContext=this;
初始化组件();
}
//绑定到按钮内容
公共列表按钮
{
获取{return\u buttonNames;}
设置
{
_按钮名称=值;
PropertyChanged?.Invoke(这是新的propertychangedventargs(nameof(ButtonNames));
}
}
私有列表按钮名称;
//包含当前窗口,用于访问IViewButtons的windows实现
IViewButtons当前窗口;
私有无效BtnView1_单击(对象发送者,路由目标e)
{
Window1 Window1=新的Window1();
currentWindow=window1;
ButtonNames=currentWindow.ButtonNames;
window1.Show();
}
私有无效BtnView2_单击(对象发送者,路由目标e)
{
Window2 Window2=新的Window2();
currentWindow=window2;
ButtonNames=currentWindow.ButtonNames;
window2.Show();
}
私有作废按钮\u单击(对象发送者,路由目标)
{
//将事件转发到windows事件处理程序
当前窗口。按钮单击(发送者,e);
}
}
Hi@RolandJS,非常感谢。我可以很容易地适应我的——稍微复杂一点的——情况,它就像一种魅力。非常感谢,并致以最良好的问候。